JavaScript: выполнить кучу асинхронных методов с одним обратным вызовом - PullRequest
14 голосов
/ 26 мая 2010

Мне нужно выполнить несколько асинхронных методов (клиентская база данных SQLite) и вызвать только один последний обратный вызов.

Конечно, уродливый способ:

execAll : function(callBack) {
        asynch1(function() {
            asynch2(function() {
                ...
                asynchN(function() {
                    callBack();
                })
            })
        });
    }

Но я знаю, что есть лучшие способы сделать это. Интуитивно я бы обнаружил, когда весь обратный вызов был вызван со счетчиком для вызова окончательного обратного вызова.

Я думаю, что это обычный дизайн-шаблон , поэтому, если кто-то может указать мне правильное направление ...

Заранее спасибо!

Ответы [ 4 ]

20 голосов
/ 26 мая 2010

это просто

var callback = (function(){
    var finishedCalls = 0;
    return function(){
        if (++finishedCalls == 4){
             //execute your action here
        }
    };
})();

Просто передайте этот обратный вызов всем вашим методам, и как только он будет вызван 4 раза, он выполнится.

Если вы хотите использовать фабрику для этого, вы можете сделать следующее

function createCallback(limit, fn){
    var finishedCalls = 0;
    return function(){
        if (++finishedCalls == limit){
             fn();
        }
    };
}


var callback = createCallback(4, function(){
    alert("woot!");
});


async1(callback);
async2(callback);
async3(callback);
async4(callback);
8 голосов
/ 09 июля 2010

Я написал несколько асинхронных утилит, которые могут оказаться полезными для вас, например:

function(callback) {
    async.series([
        asynch1(),
        asynch2(),
        ...
        asynchN()
    ], callback);
}

Или, если вы хотите запустить их параллельно, как:

function(callback) {
    async.parallel([
        asynch1(),
        asynch2(),
        ...
        asynchN()
    ], callback);
}

Есть множество других полезных функций, таких как асинхронное отображение / уменьшение:

http://caolanmcmahon.com/async.html

Надеюсь, это поможет!

2 голосов
/ 15 мая 2013

Вы должны рассмотреть возможность использования отложенного шаблона для асинхронных методов. Вы можете получить больше информации из этого вопроса и ответов StackOverflow:

В чем разница между отложенным, обещанием и будущим в JavaScript?

Отмеченный ответ от jnewman был действительно хорош!

Надеюсь, это поможет.

0 голосов
/ 05 августа 2017

Обещания могут помочь справиться с этим. Существует два основных сценария - параллельный и последовательный. Параллельно можно выполнить с помощью Promise.all (), последовательный - более сложный - задача B может начаться только после выполнения задачи A. Вот простой пример:

// returns a promise that resolves as the task is done
const wrap = (fn, delay) => new Promise(resolve => setTimeout(_ => resolve(fn()), delay));
const task = (fn, delay) => delay ? wrap(fn, delay) : Promise.resolve(fn());

// given a list of promises, execute them one by one.
const sequence = async l => l.reduce(async (a, b) => [].concat(await a, await b));

const tasks = [
    task(_ => console.log("hello world")),
    task(_ => console.log("hello future"), 1000)
];

sequence(tasks).then(_ => console.log("all done"));

Вам может потребоваться перевод ES6 / 7, чтобы это работало в браузерах или более старых версиях узлов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...