Callbacks 和 promise 很好地解决了异步操作。Promise 比 callback 改进的地方在提供了扁平的语法,特别是遇到链式 promise 的时候。promise 包含的操作符 allSettled、any、then、catch 使得应对复杂的异步操作更自如。
ES2017 引入了 提供了简洁语法的 Async/Await。事实上,async/await 就是 promise;它们在这些关键词上提供抽血层。
Async
async 关键字可以应用在任何函数(声明、表达式、回调),即所有这些返回一个 promise 。任何不是 promise 的值都会包装到 promise 的 resolve 中。
代码语言:javascript复制async function foo() {
return "Parwinder" // returning a string but `async` will ensure it is wrapped in a promise
}
foo().then((data) => { // we can safely use then because async function foo returns a promise
console.log(data); // Parwinder
})
我们同样也可以在 foo 函数中返回 promise 效果一样,但是这并不是必须:
代码语言:javascript复制async function foo() {
return Promise.resolve("Parwinder")
}
foo().then((data) => {
console.log(data); // Parwinder
})
注:虽然 async 函数的返回值表现的就像被包裹了一个 Promise.resolve 但是它们并不相等。若返回值是一个 promise,async 函数返回一个不同的 promise 对象,而 Promise.resolve 返回的是同一个。当你想检测 async 函数返回值和原始 promise 的相等性时就会遇到麻烦。MDN
代码语言:javascript复制const p = new Promise((res, rej) => {
res(1);
})
async function asyncReturn() {
return p;
}
function basicReturn() {
return Promise.resolve(p);
}
console.log(p === basicReturn()); // true
console.log(p === asyncReturn()); // false
Await
await 关键字使 JavaScript 等待 promise 完成且返回其结果,同时它只能被用在 async 函数中。
代码语言:javascript复制async function foo() {
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Parwinder"); // resolves with "Parwinder" after 2 seconds
}, 2000);
});
// will not move to the next line until myPromise resolves/rejects
const name = await myPromise;
// the execution pauses (or awaits) for the promise
console.log(name); // Parwinder
}
foo();
就像上面你看到的 await 关键字提供了比 promise.then 更清晰的语法。