翻译正在进行中。

 async function 声明用于定义一个返回 AsyncFunction 对象的异步函数。异步函数是指通过事件循环异步执行的函数,它会通过一个隐式的 Promise 返回其结果。但是如果你的代码使用了异步函数,它的语法和结构会更像是标准的同步函数。
 

你还可以使用 异步函数表达式 来定义异步函数。

语法

async function name([param[, param[, ... param]]]) { statements }
name
函数名称。
param
要传递给函数的参数的名称。
statements
函数体语句。

返回值

一个返回的Promise对象会以async function的返回值进行解析(resolved),或者以该函数抛出的异常进行回绝(rejected)。

描述

当调用一个 async 函数时,会返回一个 Promise 对象。当这个 async 函数返回一个值时,Promise 的 resolve 方法会负责传递这个值;当 async 函数抛出异常时,Promise 的 reject 方法也会传递这个异常值。

async 函数中可能会有 await 表达式,这会使 async 函数暂停执行,等待 Promise  的结果出来,然后恢复async函数的执行并返回解析值(resolved)。

    注意, await 关键字仅仅在 async function中有效。如果在 async function函数体外使用 await ,你只会得到一个语法错误(SyntaxError)。

async/await的用途是简化使用 promises 异步调用的操作,并对一组 Promises执行某些操作。正如Promises类似于结构化回调,async/await类似于组合生成器和 promises。

示例

简单例子

var resolveAfter2Seconds = function() {
  console.log("starting slow promise");
  return new Promise(resolve => {
    setTimeout(function() {
      resolve(20);
      console.log("slow promise is done");
    }, 2000);
  });
};

var resolveAfter1Second = function() {
  console.log("starting fast promise");
  return new Promise(resolve => {
    setTimeout(function() {
      resolve(10);
      console.log("fast promise is done");
    }, 1000);
  });
};

var sequentialStart = async function() {
  console.log('==SEQUENTIAL START==');

  // 如果 await 操作符后的表达式不是一个 Promise 对象, 则它会被转换成一个 resolved 状态的 Promise 对象
  const slow = await resolveAfter2Seconds();

  const fast = await resolveAfter1Second();
  console.log(slow);
  console.log(fast);
}

var concurrentStart = async function() {
  console.log('==CONCURRENT START with await==');
  const slow = resolveAfter2Seconds(); // 立即启动计时器
  const fast = resolveAfter1Second();

  console.log(await slow);
  console.log(await fast); // 等待 slow 完成, fast 也已经完成。
}

var stillSerial = function() {
  console.log('==CONCURRENT START with Promise.all==');
  Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then(([slow, fast]) => {
    console.log(slow);
    console.log(fast);
  });
}

var parallel = function() {
  console.log('==PARALLEL with Promise.then==');
  resolveAfter2Seconds().then((message)=>console.log(message)); // 这种情况下可以简写成 console.log(resolveAfter2Seconds());
  resolveAfter1Second().then((message)=>console.log(message));
}

sequentialStart(); // 两秒后,输出 “slow”,1秒之后,输出“fast”
// 等到 sequentialStart() 完成
setTimeout(concurrentStart, 4000); // 两秒之后,输出“slow”,然后输出“fast”
// 等到 setTimeout(concurrentStart, 4000) 完成
setTimeout(stillSerial, 7000); // 和concurrentStart一样
// 等到 setTimeout(stillSerial, 7000) 完成
setTimeout(parallel, 10000); // 真正的并行运行:一秒之后,输出“fast”,然后1秒之后,输出“slow”

不要将awaitPromise.then混淆

sequentialStart中,程序为第一个await停留了2秒,然后又为第二个await停留了1秒。直到第一个计时器结束后,第二个计时器才被创建。
在 concurrentStart中,两个计时器均被创建,然后一起被await。这两个计时器同时运行的,但await的调用仍然是按顺序运行的,这意味着第二个await会等到第一个await运行结束。这使得代码完成运行只需要2秒,而不是3秒。这2秒是由最慢的计时器决定的。

使用了Promise.allstillSerial的例子中也存在同样的情况。

如果你希望同时await两个或者是更多的Promise对象,你必须使用Promise.then,正如例子中parallel所做的那样。

通过async方法重写 promise 链

返回 Promise的 API 将会被用于 promise 链,它会将函数分成若干部分。例如下面代码:

function getProcessedData(url) {
  return downloadData(url) // 返回一个 promist 对象
    .catch(e => {
      return downloadFallbackData(url)  // 返回一个 promise 对象
    })
    .then(v => {
      return processDataInWorker(v); // 返回一个 promise 对象
    });
}

可以通过如下所示的一个async函数重写:

async function getProcessedData(url) {
  let v;
  try {
    v = await downloadData(url); 
  } catch (e) {
    v = await downloadFallbackData(url);
  }
  return processDataInWorker(v);
}

注意,在上述示例中,return 语句中没有 await 操作符,因为 async function 的返回值将被隐式地传递给 Promise.resolve

规范

Specification Status Comment
ECMAScript Latest Draft (ECMA-262)
async function
Draft 最初定义于ES2017.
ECMAScript 2017 (ECMA-262)
async function
Standard  

浏览器兼容

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidEdge MobileFirefox for AndroidOpera for AndroidiOS SafariSamsung InternetNode.js
Basic supportChrome Full support 55Edge Full support YesFirefox Full support 52IE No support NoOpera Full support 42Safari Full support 10.1WebView Android Full support YesChrome Android Full support 55Edge Mobile Full support YesFirefox Android Full support 52Opera Android Full support 42Safari iOS Full support 10.1Samsung Internet Android Full support 6.0nodejs Full support 7.6.0
Full support 7.6.0
Full support 7.0.0
Disabled
Disabled From version 7.0.0: this feature is behind the --harmony runtime flag.

Legend

Full support  
Full support
No support  
No support
User must explicitly enable this feature.
User must explicitly enable this feature.

参见

文档标签和贡献者

最后编辑者: lmislm,