es 异步流程(三)之async/await篇

3 篇文章 0 订阅

一、前言

在上一篇文章中我记录了 generator 的用法:es 异步流程(二)之generator篇

不了解generator语法的话,建议先看懂generator再看async。

generator和自动化执行器的配合已经使得异步编程非常地简洁了,但是还会有人觉得:“generator函数语义还不够直观,每次调用都需要用一次 执行器函数...”。

后来,在es2017中便出现了async/await 规范。async / await 并不是全新的东西,它只是generator的语法糖,它的底层依然是使用generator 和 promise 。

二、使用

1. async 函数格式

 与generator函数使用 " * " 不同,async 函数 使用 " async "来表示该函数是异步操作函数,语义相比" * "直观很多。

async function asyncFn(){
    ...
}

 另外,async函数的返回值是 Promise

async function asyncFn(){
	var r1 = 100;
	var r2 = 200;
	return r1 + r2;
}
asyncFn().then((res)=>{
	console.log(res); //输出:300
})

2. await

async 函数是内置执行器的,也就是说可以省略使用 co 这些库,大大方便了使用。

await 相当于 generator 中的 yield 。但与yield使用co不同的是,await 后面可以是 promise,也可以是基本类型。

function step1(){
	return new Promise((resolve,reject)=>{
		setTimeout(()=>{
 			resolve(100);
		},1000);
	});
}

async function asyncFn(){
	var r1 = await step1(); // promise
	var r2 = await 200;    //基本类型 (r2 = 200)
	return r1+r2;
}

asyncFn().then((res)=>{
	console.log(res);    //输出:300
})

根据 await 后面的值类型可以分成三种情况:

   1. 基本类型(number、string、boolean、无then对象等)

       直接返回该值

   2.promise对象

       返回resolve的值,如果reject则结束函数,并在async函数返回的promise.catch中截获错误。

   3.thenable对象(即定义有then的对象)

       当作promise来处理

需要注意的是,await 只能在async函数中使用,否则会报错:

function syncFn(){
    await 100; //报错:await is only valid in async function
}

 有时候该错误很难发现:

async function asyncFn(){
	var arr = [1,2,3,4];
	arr.forEach( (element, index)=>{  //foreach语句里传入的不是一个async函数!
		await element;
	});
}

 实际上,传入forEach中的是一个新的函数,而该函数如果不是async函数又使用await的话则报错。

让我们来改一下:

function asyncFn(){    //这里没有async了
	var arr = [1,2,3,4];
	arr.forEach( async (element, index)=>{ //在这里添加async
		await element;
	});
}

 但是这个函数可能会与你想象的不一样。它不是串行执行的,因为 forEach函数 以及每个 async函数 都是独立的缘故,这些async实际是同时执行的。

3.异步应用

串行执行异步操作:

function step1(){
	return new Promise((resolve,reject)=>{
		setTimeout(()=>{
 			resolve(100);
		},1000);
	});
}
function step2(v=0){
	return new Promise((resolve,reject)=>{
		setTimeout(()=>{
 			resolve(200+v);
		},1000);
	});
}
async function asyncFn(){
	var r1 = await step1();
	var r2 = await step2(r1);
	return r2;
}

asyncFn().then((res)=>{
	console.log(res); //输出:300
})

并行执行异步操作:

async function asyncFn(){
	var r = await Promise.all([step1(),step2()]) //step1和step2函数用上面例子的
	return r;
}

asyncFn().then((res)=>{
	console.log(res); //输出:[100 , 200]
})

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值