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 на сервере А и пользователю возврщается результат .

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

kobezzza 10.01.2014 18:55

Цитата:

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

Ну сокетами как вариант, или простыми HTTP запросами, да ваще хоть как угодно.

Если лень писать самому, то можно взять какойнить готовый облачный сервис, я например юзаю pusher для обмена сообщениями между серверами в облаке.

https://github.com/pusher/pusher-node-server
https://github.com/dirkbonhomme/pusher-client-node

Dorian_bs 10.01.2014 18:58

kobezzza, Большое спасибо за помощь!


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