在制作func_a() 和func_b() 的promisified 版本后,您可以使用Promise.all() 和await 在async function 中不使用计数器的聚合结果:
const promisify = fn => function () {
return new Promise((resolve, reject) => {
// forward context and arguments of call
fn.call(this, ...arguments, (error, result) => {
if (error) {
reject(error)
} else {
resolve(result)
}
})
})
}
const func_a_promisified = promisify(func_a)
const func_b_promisified = promisify(func_b)
async function loop_a_b (num1, num2) {
// await pauses execution until all asynchronous callbacks have been invoked
const results_a = await Promise.all(
Array.from(Array(num1).keys()).map(i => func_a_promisified(i))
)
const results_b = await Promise.all(
Array.from(Array(num2).keys()).map(j => func_b_promisified(j))
)
return {
a: results_a,
b: results_b
}
}
// usage
loop_a_b(3, 4).then(({ a, b }) => {
// iff no errors encountered
// a contains 3 results in order of i [0..2]
// b contains 4 results in order of j [0..3]
}).catch(error => {
// error is first encountered error in chronological order of callback results
})
为了简化 Array.from(...).map(...) 混乱,您可以编写一个帮助程序 generator function 来同时调用异步函数:
function * loop_fn_n (fn, n) {
for (let i = 0; i < n; i++) {
yield fn(n)
}
}
然后将loop_a_b改为:
async function loop_a_b (num1, num2) {
// await pauses execution until all asynchronous callbacks have been invoked
const results_a = await Promise.all(
loop_fn_n(func_a_promisified, num1)
)
const results_b = await Promise.all(
loop_fn_n(func_b_promisified, num2)
)
return {
a: results_a,
b: results_b
}
}
正如@OleksiiTrekhleb 指出的那样,我在这里实现的promisify 函数也可以在Node.js 核心模块util 中使用。