全部 / 前端 / 技术 · 2022年4月6日 0

37 – Async/Await : 简介

Callbacks 和 promise 很好地解决了异步操作。Promise 比 callback 改进的地方在提供了扁平的语法,特别是遇到链式 promise 的时候。promise 包含的操作符 allSettledanythencatch 使得应对复杂的异步操作更自如。

ES2017 引入了 提供了简洁语法的 Async/Await。事实上,async/await 就是 promise;它们在这些关键词上提供抽血层。

Async

async 关键字可以应用在任何函数(声明、表达式、回调),即所有这些返回一个 promise 。任何不是 promise 的值都会包装到 promise 的 resolve 中。

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 效果一样,但是这并不是必须:

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

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 函数中。

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 更清晰的语法。