如何等待async.parallel



假设我下面有一个async.parallel代码示例,用于并行运行异步函数,并等待它们完成后再根据结果运行代码。

async.parallel({
one: async (callback) => {/* ... some async code */ return someResult},
two: async (callback) => {/* ... some async code */ return someResult},
three: async (callback) => {/* ... some async code */ return someResult},
},(err,results) => {
if (err) { /* … error handling code */ }
/* … continued code */
debug(results)      // prints "results" object successfully without problems
});

我想做的是将继续代码(在传递给async.parallel的所有函数完成后继续/运行的代码(放在async.parallel之外。

我试过这个:

const results = await async.parallel({
one: async (callback) => {/* ... some async code */ return someResult},
two: async (callback) => {/* ... some async code */ return someResult},
three: async (callback) => {/* ... some async code */ return someResult},
},(err,results) => {
if (err) { /* … error handling code */ }
debug("test print1: from inside async.parallel callback function");
// called/printed after "test print2" meaning that async.parallel isn't awaited.
return results;
});
/* … continued code */
debug("test print2: from outside async.parallel");
// printed before "test print1" meaning that async.parallel isn't awaited.
debug(results)      // prints "undefined"

这个:

let results_outer;
await async.parallel({
one: async (callback) => {/* ... some async code */ return someResult},
two: async (callback) => {/* ... some async code */ return someResult},
three: async (callback) => {/* ... some async code */ return someResult},
},(err,results) => {
if (err) { /* … error handling code */ }
debug("test print1: from inside async.parallel callback function");
// printed after "test print2" meaning that async.parallel isn't awaited.
results_outer = results;
});
/* … continued code */
debug("test print2: from outside async.parallel");
// printed before "test print1" meaning that async.parallel isn't awaited.
debug(results_outer)      // prints "undefined"

我的问题是,如何等待async.parallel并成功获得结果对象?


建议的解决方案/替代方案:(非是我的问题的解决方案,但它们可能是有用的临时替代方案(

备选方案1:(我不喜欢,因为它看起来比异步并行更丑/更麻烦(

const results = await Promise.all([
new Promise( (resolve, reject) => {/* ... some async code */ resolve('some result 1')} ),
new Promise( (resolve, reject) => {/* ... some async code */ resolve('some result 2')} ),
new Promise( (resolve, reject) => {/* ... some async code */ resolve('some result 3')} )
]);
debug(results);      // prints "results" object successfully without problems

关于备选方案1:
为了简化备选方案1,我们可以创建promisify(some_function):

const results = await Promise.all([
promisfy(some_functionOne),
promisfy(some_functionTwo),
promisfy(some_functionThree)
]);
debug(results);      // prints "results" object successfully without problems
function promisfy(some_function) {
const promise = new Promise( (resolve, reject) => {
some_function_return_value = await some_function();
resolve(some_function_return_value);
} );
return promise;
}

为了进一步简化备选方案1:

async_parallel([some_functionOne, some_functionTwo, some_functionThree]);
debug(results);      // prints "results" object successfully without problems
function async_parallel(functions_to_run) {
let promises = functions_to_run.map(function_to_run => promisfy(function_to_run));
const results = await Promise.all(promises);
return results;
}

我们最终可能会构建一个类似于异步库的库,并重新发明轮子,特别是当我们需要concat、瀑布等功能时。

由于数据库的现代版本已经支持promise,因此不需要async库来实现这一点。相反,你可以这样做:

let results = await Promise.all([
Car_model.findOne(...), 
Car_model.findOne(...), 
Car_model.findOne(...)
]);
console.log(results);

当然,这段代码需要在async函数中,这样才能使用await

只需删除回调函数,async.parallel将返回Promise

如果没有传递回调,

async.parallel将返回promise。

const results = await async.parallel({
one: async (callback) => {/* ... some async code */ return someResult},
two: async (callback) => {/* ... some async code */ return someResult},
three: async (callback) => {/* ... some async code */ return someResult},
});
debug(results)      // prints "results" object successfully without problems

为了处理错误,将代码放入try..catch:

try {
let results = await async.parallel({
one: async (callback) => {/* ... some async code */ return someResult},
two: async (callback) => {/* ... some async code */ return someResult},
three: async (callback) => {/* ... some async code */ return someResult},
});
debug(results);
} catch(err) {
/* … error handling code */
}

最新更新