Страницы

Поиск по вопросам

четверг, 27 декабря 2018 г.

Синхронизация выполнения функций

Синхронизация в javascript. Например, есть три функции:
func1(function(){}); // асинхронная с callback func2(function(){}); // асинхронная с callback func3(); // синхронная возвращает true-false
Нужно, чтобы после того, как func1 и func2 вызвали свои callback, а func3 вернул true, вызвать функцию func4
Как правильно и лучше всего это сделать, если ли стандартная техника для такого?


Ответ

Вариант 1 - наиболее разумный - использовать Promise и Deferred
http://api.jquery.com/promise/
http://api.jquery.com/jQuery.when/
http://api.jquery.com/deferred.promise/
Код:
var d1 = $.Deferred(); var d2 = $.Deferred(); var d3 = $.Deferred();
func1(function() { d1.notify(); }); func2(function() { d2.notify(); }); func3(); d3.notify();
$.when( d1, d2, d3 ).done(function () { // Выполнить результирующее действие. });
Вариант 2 - завести счетчик количества выполняемых функций (не требует библиотек) и отслеживать выполнение в общем callback-е. Возможно также вместо счетчика использовать массив с именами функций.
var currentCallbacks = 0; var expectedCallbacks = 3;
var commonCallback = function() { currentCallbacks++; if (currentCallbacks == expectedCallbacks) { // Выполнить результирующее действие. } };
func1(function(){commonCallback();}); func2(function(){commonCallback();}); func3(); commonCallback();
Вариант 3 - _underscore.js имеет функцию after. Если библиотека уже подключена, можно использовать её функционал.
Вернёт копию функции function, модифицированную таким образом, что она будет запущена только после того, как будет вызвана count раз. Удобно использовать при работе с асинхронными запросами, например, чтобы убедиться, что все обращения к серверу завершились.
var commonCallback = _.after(3, function() { // Выполнить результирующее действие... });
func1(function() { commonCallback(); }); func2(function() { commonCallback(); }); func3(); // Внутри должен перед выходом из функции вызываться commonCallback();
var functions = [func1, func2, func3]; var runProcess = function() { _.each(functions, function(func) { func(); }); };
runProcess();
Вариант 4 - построить цепочку вызовов, но убивает все плюсы параллелизма.
func1(callback1);
function callback1() { ... func2(callback2); }
function callback2() { ... func3(); // Выполнить результирующее действие. }

Комментариев нет:

Отправить комментарий