Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Потоки данных и параллельное выполнение функций (https://javascript.ru/forum/misc/44195-potoki-dannykh-i-parallelnoe-vypolnenie-funkcijj.html)

Dorian_bs 10.01.2014 17:49

Потоки данных и параллельное выполнение функций
 
Всем привет!
Разбираюсь с логикой выполнения функций в nodejs.
Дело в том, что у меня есть цикл, который обрабатывает много данных и проводит сложные вычисления.

Я так понимаю, что добиться параллельного выполнения функций в одном потоке нельзя. Даже если вызвался callback - он не выполнится, пока в потоке на данный момент происходят вычисления и пока очередь не дойдет до него.

Я правильно понимаю?)

cyber 10.01.2014 18:02

Цитата:

Сообщение от Dorian_bs
Даже если вызвался callback - он не выполнится, пока в потоке на данный момент происходят вычисления и пока очередь не дойдет до него.

Если к примеру запрос к базе данных идет, то запрос будет асинхроным и callback выполниться когда прийдет ответ из базы, а если к примеру использовать callback в forEach то эта операция будет синхронной.

Цитата:

Сообщение от Dorian_bs
Дело в том, что у меня есть цикл, который обрабатывает много данных и проводит сложные вычисления.

Просто пример как это можно сделать, сервер А принял запрос на длителььную задачу что бы не блокировать обработку запросов выполнения сложного вычесления передано серверу Б, после выполнения сервере Б, вызывается callback на сервере А и пользователю возврщается результат .

kobezzza 10.01.2014 18:03

Я уже писал тебе про это. В рамках потока всё выполняется последовательно, но ты можешь разбить свой цикл на множество подциклов и выполнять его поэтапно, т.е. прошёл n итераций, прервался, ждёшь пока выполнятся другие задания, потом опять начал и т.д.

Нужные функции в node для этого - это setImmediate и nextTick, НО если у тебя задача требует поддержки потоков в языке, то крайне глупо использовать для этого JS, возьми например Java.

kobezzza 10.01.2014 18:07

Цитата:

Сообщение от cyber (Сообщение 291485)
Если к примеру запрос к базе данных идет, то запрос будет асинхроным и callback выполниться когда прийдет ответ из базы, а если к примеру использовать callback в forEach то эта операция будет синхронной.

Ты написал глупости:) Всё зависит от интерфейса АПИ, тот же пресловутый forEach легко делается асинхронным с помощью дробления через setImmediate или nextTick (смотри либу async).

В случае асинхронного callback он выполнится не сразу как придёт, а сразу как до него дойдёт очередь после того, как он пришёл, т.е. если залочить поток бесконечным циклом, то callback никогда не всплывёт.

В общем нужно помнить, что пока JS что-то делает (бегает по циклам, складывает числа), то все уже пришедшие callback-и будут томится в темнице стека-событий ожидая освобождения потока.

Dorian_bs 10.01.2014 18:13

cyber, спасибо за ответ!
kobezzza, Вот нарисовал, как я представляю логику) Вернее как я начал представлять ее))

Получается благодаря nextTick мы прерываем выполнение функции до следующей итерации event-loop?
То есть даем возможность дальше выполниться всем остальным функциям?
А с новой итерацией уже выполняем то, что задано в nextTick.
Все верно?


cyber 10.01.2014 18:14

Цитата:

Сообщение от kobezzza
Всё зависит от интерфейса АПИ, тот же пресловутый forEach легко делается асинхронным с помощью дробления

Я как пример говорю, про forEach в том виде в котором он есть.
Цитата:

Сообщение от kobezzza
В случае асинхронного callback он выполнится не сразу как придёт, а сразу как до него дойдёт очередь после того, как он пришёл, т.е. если залочить поток бесконечным циклом, то callback никогда не всплывёт.

Да, согласен тут я не уточнил что он становиться в очередь, и пока до него не дойдет очередь он не будет вызван.
Цитата:

Сообщение от kobezzza
(смотри либу async).

Хорошая либа;)

kobezzza 10.01.2014 18:20

Цитата:

Сообщение от Dorian_bs (Сообщение 291491)
kobezzza, Получается благодаря nextTick мы прерываем выполнение функции до следующей итерации event-loop?
То есть даем возможность дальше выполниться всем остальным функциям?
А с новой итерацией уже выполняем то, что задано в nextTick.
Все верно?

Не, никаких прерываний. Ты просто передаёшь в setImmediate функцию, и она выполнится на следующей итерации событийного цикла, т.е. искуственно разбиваешь свою функцию на множество подфункций. Но в остальном ход мыслей в нужном направлении движется.

Разница между nextTick и setImmediate в том, что одни функции выполняются до I/O,а другие после.

Тут следует сказать, что выполнение setTimeout и setInterval могут быть как до I/O так и после, т.е. их для этих целей лучше не юзать.

***

Прерывания кстати тоже возможны, с помощью генераторов (см. оператор yield, в node они уже поддеживаются).

Dorian_bs 10.01.2014 18:28

Цитата:

Сообщение от kobezzza (Сообщение 291495)
Разница между nextTick и setImmediate в том, что одни функции выполняются до I/O,а другие после.

kobezzza, То есть функции обернутые в setImmediate будут выполняться в конце следующей итерации?)

kobezzza 10.01.2014 18:33

Цитата:

Сообщение от Dorian_bs (Сообщение 291496)
kobezzza, То есть функции обернутые в setImmediate будут выполняться в конце следующей итерации?)

Ну грубо говоря да. А nextTick в конце текущей, поэтому setImmediate обычно юзают для "разгрузки" больших операций.

process.nextTick(function () {
    console.log(1);

    process.nextTick(function () {
        console.log(2);
    });
});

setImmediate(function () {
    console.log(3);

    process.nextTick(function () {
        console.log(1);

        process.nextTick(function () {
            console.log(2);
        });
    });
});

console.log(4);


// 4 1 2 3 1 2

Dorian_bs 10.01.2014 18:51

kobezzza, большое спасибо! Теперь все куда более понятно!)

Цитата:

Сообщение от cyber (Сообщение 291485)
Просто пример как это можно сделать, сервер А принял запрос на длителььную задачу что бы не блокировать обработку запросов выполнения сложного вычесления передано серверу Б, после выполнения сервере Б, вызывается callback на сервере А и пользователю возврщается результат .

А вы не можете подсказать, существуют ли какие либо модули для обмена данными между работающими серверами?


Часовой пояс GMT +3, время: 14:07.