async函数
ECMAScript 2017规范引入了 async 函数,该函数的主要目的就是简化使用 Promises,异步调用的操作,并对一组 Promises 执行某些操作。正如 Promises 类似于结构化回调,async / await类似于组合生成器和 Promises。
示例代码如下:
function resolveAfter2Seconds() { return new Promise(resolve =>{ setTimeout(()=>{ resolve('resolved'); },2000); }); } /*// promise方式 let promise = resolveAfter2Seconds(); promise.then((value)=>{ console.log(value); });*/ // async函数方式 async function asyncCall() { console.log('calling'); var result = await resolveAfter2Seconds(); console.log(result);//resolved } asyncCall();
一、async函数的语法结构
(1)异步函数声明式
异步函数声明式用于定义一个返回Promise对象的异步函数。异步函数是指通过事件循环异步执行的函数,它会通过一个隐式的Promise返回其结果。但是如果代码使用了异步函数,它的语法和结构会更像是标准的同步函数。
async function name([param[,param[,...param]]]){statements}
name : 表示函数名称。
param : 要传递给函数的参数的名称。
statements : 表示函数体语句 。
(2)异步函数表达式
异步函数表达式用于在表达式中定义异步函数。
let name = async function([param1[,param2[,...parmaN]]]){statements}
name : 表示函数名称。
param : 要传递给函数的参数的名称。
statements : 表示函数体语句 。
异步函数表达式与异步函数语句非常相似,语法也基本相同。他们之间的主要区别在于异步函数表达式可以省略函数名称来创建一个匿名函数。
返回Promise 对象
async 函数返回一个Promise对象。async 函数内部 return语句返回的值,会成为then方法回调函数的参数。
// async 函数返回promise对象 async function myAsync() { return 'hello world'; } let promise = myAsync(); promise.then((value) => { console.log(value);//hello world })
二、await表达式
await 表达式用于等待一个Promise 对象,它只能在异步函数中使用。
[return_value] = await expression
expression :一个 Promise 对象或者任何要等待的值。
return_value : 返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身。
function createPromise() { return new Promise((resolve, reject) => { setTimeout(()=>{ resolve('执行成功啦'); }); }); } async function myAsync() { console.log('当前异步函数被调用啦'); var result = await createPromise(); console.log('Promise对象执行的结果:' + result) } myAsync();
错误处理
为了防止错误,将其放置在 try_catch 语句中。
function createPromise() { return new Promise((resolve, reject) => { setTimeout(()=>{ reject('执行失败啦'); }); }); } async function myAsync() { console.log('当前异步函数被调用啦'); try{ var result = await createPromise(); }catch (e) { console.log('Promise对象执行的结果:' + e) } } myAsync();
Promise 对象执行一组 Promise 对象
let promise1 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('one'); },100); }); let promise2 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('two'); },200); }); let promise3 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('three'); },300); }); async function myAsync() { let result1 = await promise3; console.log(result1); let result2 = await promise2; console.log(result2); let result3 = await promise1; console.log(result3); } myAsync();
三、注意事项
try … catch 语句
await命令后面的Promise 对象,运行结果可能是rejected,所以最好把 await表达式放置在try…catch 代码块中。
多个await表达式后面的异步操作,如果不存在继发关系,最好让它们同时触发。
await 表达式的限制
await 表达式只能用在 async 函数中,如果用在普通函数,就会报错。