Мне очень нравится async.js для этой цели.
Проблема решается командой водопада:
водопад (задачи, [обратный вызов]))
Запускает массив функций последовательно, каждая из которых передает свои результаты следующему в массиве.Однако, если какая-либо из функций передает ошибку обратному вызову, следующая функция не выполняется, и основной обратный вызов немедленно вызывается с ошибкой.
Аргументы
tasks - Массив функцийДля запуска каждой функции передается обратный вызов (err, result1, result2, ...), который она должна вызывать по завершении.Первый аргумент является ошибкой (которая может быть нулевой), и любые дальнейшие аргументы будут переданы в качестве аргументов для следующей задачи.callback (err, [results]) - необязательный обратный вызов, запускаемый после завершения всех функций.Для этого будут переданы результаты обратного вызова последней задачи.
Пример
async.waterfall([
function(callback){
callback(null, 'one', 'two');
},
function(arg1, arg2, callback){
callback(null, 'three');
},
function(arg1, callback){
// arg1 now equals 'three'
callback(null, 'done');
}
], function (err, result) {
// result now equals 'done'
});
Что касается переменных req, res, они будут совместно использоваться в той же области видимости, что и функция (req, res) {}, который заключил весь вызов async.waterfall.
Мало того, async очень чист.Я имею в виду, что я изменяю множество таких случаев:
function(o,cb){
function2(o,function(err, resp){
cb(err,resp);
})
}
На первый:
function(o,cb){
function2(o,cb);
}
Затем на этот:
function2(o,cb);
Затем наthis:
async.waterfall([function2,function3,function4],optionalcb)
Это также позволяет очень быстро вызывать многие готовые функции, подготовленные для асинхронного вызова из util.js.Просто включите в цепочку то, что вы хотите сделать, убедитесь, что o, cb универсально обработан.Это значительно ускоряет весь процесс кодирования.