为了方便处理异步函数,最好的方法是使用promises和async/await
function thisTakes2Seconds() {
return new Promise(resolve => setTimeout(() => resolve(3), 200)); // 0.2 to avoid waiting :P
}
function thisTakes5Seconds() {
return new Promise(resolve => setTimeout(() => resolve(5), 500));
}
async function foo() {
const data = {};
data.x = await thisTakes2Seconds();
data.y = await thisTakes5Seconds();
// This will run once both promises have been resolved
console.log(data);
}
foo()
.then(() => console.log('done!')
.catch(err => console.error(err));
如果您希望同时执行这两个功能,您可以这样做,然后使用 Promise.all 等待两者完成
async function foo() {
const data = {};
// Promise.all returns an array where each item is the resolved
// value of the promises passed to it, maintaining the order
// So we use destructuring to assign those values
[data.x, data.y] = await Promise.all([
thisTakes2Seconds(),
thisTakes5Seconds()
]);
console.log(data);
}
如果您已经有一个使用回调的异步函数,您可以轻松地将其转换为 Promise。
function myAsyncFunction(callback) {
setTimeout(() => {
callback(Math.random());
}, 200);
}
function myAsyncFunctionPromise() {
return new Promise((resolve, reject) => {
myAsyncFunction(resolve);
// If there is an error callback, just pass reject too.
});
}
像 bluebird 这样的库已经有一个实用方法来承诺回调 API。
http://bluebirdjs.com/docs/api/promise.promisify.html
如果你在浏览器上运行它,并且需要支持过时的,你可以使用 babel 将 async/await 转换为 ES5