async函数 - JavaScript

async function关键字用来在表达式中定义异步函数。

语法

async function [name]([param1[, param2[, ..., paramN]]]) {
  statements
}

name:函数名称。可省略,省略为匿名函数。

paramN:传递给函数的参数。

statements:函数主体语句。

示例

function resolveAfter2Seconds() {
 return new Promise(resolve => {
  setTimeout(() => {
   resolve('resolved');
  }, 2000);
 });
}

async function asyncCall() {
 console.log('calling');
 var result = await resolveAfter2Seconds();
 console.log(result);
 // expected output: 'resolved'
}

asyncCall();

async function声明一个异步函数,返回一个AsyncFunction对象。

异步函数是一个通过事件循环异步操作的函数,使用隐式Promise作为返回结果,对Promise进行解析。

异步函数可以包含一个await表达式,用于暂停异步函数的执行,等待Promise解析后,然后继续异步函数的执行并计算解析后的值。

使用异步函数的代码与同步函数相差无几。

注:await关键字只在异步函数中有效。在异步函数体外使用,会出现语法错误。当异步函数暂停时,调用函数继续执行(异步函数返回的隐式Promise)。

并行

如果希望并行执行多个作业,须使用await Promise.all([job1(), job2()])。

重写调用链

返回Promise的API会产生一个Promise调用链,将函数分成多个部分,如下所示:

function getProcessedData(url) {
 return downloadData(url) // returns a promise
  .catch(e => {
   return downloadFallbackData(url); // returns a promise
  })
  .then(v => {
   return processDataInWorker(v); // returns a promise
  });
}
可以异步功能重写Promise调用链:
function getProcessedData(url) {
 return downloadData(url) // returns a promise
  .catch(e => {
   return downloadFallbackData(url); // returns a promise
  })
  .then(v => {
   return processDataInWorker(v); // returns a promise
  });
}

使用异步函数重写:

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

注:示例中,return语句后没有await,因为,异步函数返回值经过Promise.resolve包装。

var promise1 = Promise.resolve(123);
promise1.then(function(value) {
 console.log(value);
 // expected output: 123
});

隐式包装

返回Promise.resolve包装后的值,并不意味着return await promiseValue,在功能上仅等同于return promiseValue。

async function getProcessedData(url) {
 let v;
 try {
  v = await downloadData(url);
 } catch(e) {
  v = await downloadFallbackData(url);
 }
 try {
  return await processDataInWorker(v); // Note the `return await` vs. just `return`
 } catch (e) {
  return null;
 }
}

如果,processDataInWorker出现异常,返回值则是一个空值,而非Promise rejects。

表达式与语句

异步函数表达式与异步函数语句非常相似,语法也几乎相同。区别在于函数名,在异步函数表达式中可省略函数名称,创建匿名函数。