与 Promises 相比,异步功能

async 功能不替代 Promise 类型; 他们添加语言关键字,使承诺更容易调用。它们是可以互换的:

async function doAsyncThing() { ... }

function doPromiseThing(input) { return new Promise((r, x) => ...); }

// Call with promise syntax
doAsyncThing()
    .then(a => doPromiseThing(a))
    .then(b => ...)
    .catch(ex => ...);

// Call with await syntax
try {
    const a = await doAsyncThing();
    const b = await doPromiseThing(a);
    ...
}
catch(ex) { ... }

任何使用 promises 链的函数都可以使用 await 重写:

function newUnicorn() {
  return fetch('unicorn.json')                     // fetch unicorn.json from server
  .then(responseCurrent => responseCurrent.json()) // parse the response as JSON
  .then(unicorn =>
    fetch('new/unicorn', {                         // send a request to 'new/unicorn' 
        method: 'post',                            // using the POST method
        body: JSON.stringify({unicorn})            // pass the unicorn to the request body
    })
  )
  .then(responseNew => responseNew.json())
  .then(json => json.success)                      // return success property of response
  .catch(err => console.log('Error creating unicorn:', err));
 }

可以使用 async / await 重写该功能,如下所示:

async function newUnicorn() {
  try {
    const responseCurrent = await fetch('unicorn.json'); // fetch unicorn.json from server
    const unicorn = await responseCurrent.json();        // parse the response as JSON
    const responseNew = await fetch('new/unicorn', {     // send a request to 'new/unicorn'
      method: 'post',                                    // using the POST method
      body: JSON.stringify({unicorn})                    // pass the unicorn to the request body
    });
    const json = await responseNew.json();
    return json.success                                  // return success property of response
  } catch (err) {
    console.log('Error creating unicorn:', err);
  }
}

newUnicorn()async 变种似乎返回了 Promise,但实际上有多个 await 关键字。每个人都返回了一个 Promise,所以我们真的有一系列的承诺而不是链条。

事实上,我们可以把它想象成一个 function * 发电机,每个 await 都是一个 yield new Promise。但是,下一个继续该功能需要每个承诺的结果。这就是为什么函数需要额外的关键字 async(以及调用 promises 时的 await 关键字),因为它告诉 Javascript 自动为此迭代创建一个观察者。当此迭代完成时,async function newUnicorn() 返回的 Promise 将解析。

实际上,你不需要考虑那个; await 隐藏了承诺,而 async 隐藏了生成器迭代。

你可以将 async 函数称为承诺,以及 await 任何承诺或任何 async 函数。你不需要 await 一个异步函数,就像你可以在没有 .then() 的情况下执行一个承诺一样。

如果要立即执行该代码,也可以使用 async IIFE

(async () => {
  await makeCoffee()
  console.log('coffee is ready!')
})()