JavaScript 异步功能与承诺相比

示例

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

async function doAsyncThing() { ... }

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

// 用promise语法调用
doAsyncThing()
    .then(a => doPromiseThing(a))
    .then(b => ...)
    .catch(ex => ...);

// 使用等待语法进行调用
try {
    const a = await doAsyncThing();
    const b = await doPromiseThing(a);
    ...
}
catch(ex) { ... }

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

function newUnicorn() {
  return fetch('unicorn.json')                     // 来自服务器的fetchunicorn.json
  .then(responseCurrent => responseCurrent.json()) // 将响应解析为JSON
  .then(unicorn =>
    fetch('new/unicorn', {                         // 向“新/独角兽”发送请求 
        method: 'post',                            // 使用POST方法
        body: JSON.stringify({unicorn})            // 将独角兽传递给请求主体
    })
  )
  .then(responseNew => responseNew.json())
  .then(json => json.success)                      // 返回响应的成功属性
  .catch(err => console.log('Error creating unicorn:', err));
 }

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

async function newUnicorn() {
  try {
    const responseCurrent = await fetch('unicorn.json'); // 来自服务器的fetchunicorn.json
    const unicorn = await responseCurrent.json();        // 将响应解析为JSON
    const responseNew = await fetch('new/unicorn', {     // 向“新/独角兽”发送请求
      method: 'post',                                    // 使用POST方法
      body: JSON.stringify({unicorn})                    // 将独角兽传递给请求主体
    });
    const json = await responseNew.json();
    returnjson.success                                 // 返回响应的成功属性
  } catch (err) {
    console.log('Error creating unicorn:', err);
  }
}

的这种async变体newUnicorn()似乎返回Promise,但实际上有多个await关键字。每个人都返回了一个Promise,因此实际上我们拥有的是承诺的集合,而不是链条。

实际上,我们可以将其视为function*生成器,每个生成器await都是一个yield new Promise。但是,下一个需要每个承诺的结果才能继续运行该功能。这就是为什么async函数上需要附加关键字(以及await调用promise时的关键字)的原因,因为它告诉Javascript自动为此迭代创建观察者。此迭代完成后,Promise返回的由解析。async function newUnicorn()

实际上,您不需要考虑这一点。await隐藏诺言并async隐藏生成器迭代。

您可以像调用asyncpromise一样调用函数,也可以调用await任何promise或任何async函数。您不需要await异步功能,就像无需使用即可执行promise一样。.then()

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

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