Javascript - ожидание возврата асинхронных обратных вызовов?
Какой лучший способ/библиотека для обработки нескольких асинхронных обратных вызовов? Прямо сейчас у меня есть что-то вроде этого:
_.each(stuff, function(thing){
async(thing, callback);
});
Мне нужно выполнить некоторый код после того, как обратный вызов был запущен для каждого элемента в stuff
.
Какой самый чистый способ сделать это? Я открыт для использования библиотек.
Ответы
Ответ 1
Существует большая библиотека под названием Async.js, которая помогает решать такие проблемы с помощью многих асинхронных и управляющих потоков. Он предоставляет несколько функций forEach, которые могут помочь вам выполнить обратные вызовы для каждого элемента в массиве/объекте.
Отъезд:
https://github.com/caolan/async#forEach
// will print 1,2,3,4,5,6,7,all done
var arr = [1,2,3,4,5,6,7];
function doSomething(item, done) {
setTimeout(function() {
console.log(item);
done(); // call this when you're done with whatever you're doing
}, 50);
}
async.forEach(arr, doSomething, function(err) {
console.log("all done");
});
Ответ 2
Поскольку вы уже используете Underscore, вы можете посмотреть _.after
. Он делает именно то, о чем вы просите. Из документов:
после _.after(count, function)
Создает версию функции, которая будет запускаться только после того, как она будет вызвана временем отсчета. Полезно для группировки асинхронных ответов, где вы хотите убедиться, что все асинхронные вызовы закончены, прежде чем продолжить.
Ответ 3
Я рекомендую https://github.com/caolan/async для этого. Вы можете использовать async.parallel
для этого.
function stuffDoer(thing) {
return function (callback) {
//Do stuff here with thing
callback(null, thing);
}
}
var work = _.map(stuff, stuffDoer)
async.parallel(work, function (error, results) {
//error will be defined if anything passed an error to the callback
//results will be an unordered array of whatever return value if any
//the worker functions passed to the callback
}
Ответ 4
async.parallel()/async.series должны соответствовать вашим требованиям. Вы можете предоставить окончательный ответ, который будет выполнен, когда все вызовы REST преуспеют.
async.parallel([
function(){ ... },
function(){ ... }
], callback);
async.series([
function(){ ... },
function(){ ... }
], callback);
Ответ 5
У вас есть счетчик, скажем async_count
. Увеличьте его на каждый раз, когда вы начинаете запрос (внутри цикла), и обратный вызов уменьшает его на единицу и проверяет, достиг ли нуль - если это так, все обратные вызовы вернулись.
EDIT: Хотя, если бы я был тем, кто писал это, я бы привязал запросы, а не запускал их параллельно - другими словами, у меня очередь запросов и проверка обратного вызова очереди для следующего запроса.
Ответ 6
См. мой ответ на аналогичный вопрос:
Согласование параллельного выполнения в node.js
Моя функция fork()
поддерживает счетчик внутренне и автоматически.