为了轻松处理异步函数,最好的方法是使用promises
, and 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 https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/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 http://bluebirdjs.com/docs/api/promise.promisify.html
如果你在浏览器上运行它,并且需要支持过时的浏览器,你可以使用 babel 来转译async/await
to ES5