【发布时间】:2021-08-07 08:32:01
【问题描述】:
假设我在下面有这个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: (我不喜欢,因为它看起来比 async.parallel 更丑/麻烦)
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、waterfall 等功能时。
【问题讨论】:
-
看看下面,这可能会有所帮助。 stackoverflow.com/questions/47794063/…
-
为什么不只是
let results = await Promise.all([Car_model.findOne(...), Car_model.findOne(...). Car_model.findOne(...)]);?由于您的数据库已经支持承诺,我不明白为什么需要async库。 -
这些是猫鼬模型吗?你能用 promise API 代替异步吗?
-
自从 Javascript 语言中 promise 和
async/await的进步以及 nodejs 中支持 promise 的库和内置函数越来越多,使用像async这样的库的理由越来越少或Bluebird更多。是的,仍然有一些情况,例如在执行大量并行操作时管理并发请求的数量,但大多数时候,您不再需要这些库,最好只使用现代工具进行编程Javascript 已经给你了。 -
不,最初的
async库出现在 Promises 之前,旨在管理非 Promise、普通回调异步操作。此后它已被调整为合并 Promise,但它最初设计的大部分功能现在可以在没有它的情况下使用常规 Promise 的流控制来完成,特别是当您合并async/await时。
标签: javascript node.js asynchronous async-await async.js