async/await 和 promises 密切相关。 async 函数返回承诺,await 是等待承诺解决的语法糖。
混合使用 Promise 和 async 函数的唯一缺点可能是代码的可读性和可维护性,但您当然可以将异步函数的返回值用作 Promise,以及将 await 用于返回的常规函数一个承诺。
您是否选择其中一个主要取决于可用性(您的 node.js / 浏览器是否支持async?)和您的审美偏好,但一个好的经验法则(基于我当时的偏好写作)可能是:
如果需要串行运行异步代码:考虑使用async/await:
return asyncFunction()
.then(result => f1(result))
.then(result2 => f2(result2));
对
const result = await asyncFunction();
const result2 = await f1(result);
return await f2(result2);
如果你需要嵌套的 Promise:使用 async/await:
return asyncFunction()
.then(result => {
return f1(result)
.then(result2 => f2(result, result2);
})
对
const result = await asyncFunction();
const result2 = await f1(result);
return await f2(result, result2);
如果您需要并行运行:使用 Promise。
return Promise.all(arrayOfIDs.map(id => asyncFn(id)))
建议您可以在表达式中使用await 来等待多个任务,如下所示:
*注意,这仍然是从左到右依次等待,如果您不这样做也可以期待错误。否则,由于fail fast behaviour 的Promise.all() 导致行为不同
const [r1, r2, r3] = [await task1, await task2, await task3];
(async function() {
function t1(t) {
console.time(`task ${t}`);
console.log(`start task ${t}`);
return new Promise((resolve, reject) => {
setTimeout(() => {
console.timeEnd(`task ${t}`);
resolve();
}, t);
})
}
console.log('Create Promises');
const task1 = t1(100);
const task2 = t1(200);
const task3 = t1(10);
console.log('Await for each task');
const [r1, r2, r3] = [await task1, await task2, await task3];
console.log('Done');
}())
但与Promise.all 一样,并行promise 需要在出现错误时得到妥善处理。你可以阅读更多关于here的信息。
注意不要将前面的代码与以下代码混淆:
let [r1, r2] = [await t1(100), await t2(200)];
function t1(t) {
console.time(`task ${t}`);
console.log(`start task ${t}`);
return new Promise((resolve, reject) => {
setTimeout(() => {
console.timeEnd(`task ${t}`);
resolve();
}, t);
})
}
console.log('Promise');
Promise.all([t1(100), t1(200), t1(10)]).then(async() => {
console.log('Await');
let [r1, r2, r3] = [await t1(100), await t1(200), await t1(10)]
});
使用这两种方法是不等价的。 Read more about the difference.
最后,Promise.all 是一种更简洁的方法,可以更好地扩展到任意数量的任务。