85281643 2019-06-29
认识async await 首先要从单个熟悉
官方介绍:async function
声明将定义一个返回 AsyncFunction
对象的异步函数。
个人理解:
1. 首先`async function`会申明定义一个异步执行的函数,无阻塞,不会阻塞后面代码执行 2. 该函数的返回值是一个Promise对象
执行以下代码
async function testAsync() { return '茶树菇' } console.log(testAsync()); /*打印结果: Promise result: "茶树菇" status: "resolved" “Promise”原型*/
打印结果可以看出,async 可以将其后的函数执行结果转为Promise
对象
既然如此那以下操作也是可行的
testAsync().then(r => { console.log(r); });//"茶树菇"
由以下打印结果可知async function
声明函数是异步函数
function t() { return new Promise(resolve => { resolve('hah') }) } async function t1() { const a = await t() // console.log(a); console.log('t1函数里'); } t1() console.log('我在t1函数调用后'); /*打印结果: [Log] 我在t1函数调用后 [Log] t1函数里 */
官方介绍:await
操作符用于等待一个Promise
对象。它只能在异步函数 async function
中使用。
个人理解:
官方注释await
是在等待一个Promise对象,其实没有限制,只是根据等待到的结果类型的不同有不同的操作,如果等到的就是个结果,则await
就返回这个值,如果等到的是一Promise
对象,则await
会阻塞后面代码执行,等待Promise
的结果(由于await
在async function
申明的异步执行函数,所以不会影响该函数外的其他代码执行,只影响内部)
注意:如果await
等待的Promise
执行结果除了resolve
外,还有异常处理reject
,则最好用.catch(err => err)
去接收处理异常, 例const a = await t().catch(err => err)
async function testAsync1() { return "茶树菇"; } function testAsync2() { return new Promise(resolve => { resolve('茶树菇') }) } function testAsync3() { return "茶树菇"; } async function testFn() { const v1 = await testAsync1(); const v2 = await testAsync2(); const v3 = await testAsync3(); console.log(v1);//"茶树菇" console.log(v2);//"茶树菇" console.log(v3);//"茶树菇" //由此可见`await`等待的不一定是个`Promise`对象,也可以是个值 } testFn();
async await
,对比Promise
的优缺点在哪?模拟个使用场景,如下代码
需求:随机产生一个1~2之间的随机数,用延时器模拟异步操作,判断该值,如果小于一就成功,大于一失败
//用Promise实现: function test(resolve, reject) { var timeOut = Math.random() * 2; console.log('随机数为:' + timeOut); setTimeout(function() { if (timeOut < 1) { resolve('小于1, 成功') } else { reject('大于1,失败') } }, timeOut * 1000) } new Promise(test).then((result) => { console.log(result); }).catch((reason) => { console.log(reason); })
打印结果:
function test2() { var timeOut = Math.random() * 2; console.log('随机数为:' + timeOut); return new Promise((resolve, reject) => { setTimeout(() => { if (timeOut < 1) { resolve('小于1, 成功') } else { reject('大于1,失败') } }, 1000) }) } async function asyncFn() { const v3 = await test2().catch(er => er) console.log(v3); } asyncFn()
看代码其实单一的异步处理链并不能看出async await
的优势,但是如果需要处理多个Promise
组成的处理链,就能看出区别
假设需求为:分布完成,每一步都需要上一步的结果:
//每次调用时间都增加200 function logTimeOut(n) { return new Promise(resolve => { setTimeout(() => resolve(n + 200), n) }) } //第一步 function stepOne(n) { console.log('第一步所用的时间', n); return logTimeOut(n) } //第二步将第一步的结果加上200作为第二部的初始时间 function stepTow(m, n) { console.log('第二部所用的时间',m, n); return logTimeOut(n + m) } //第三步将第二步的结果加上200作为第三步的初始时间 function stepThree(k, m, n) { console.log('第三部所用的时间', k, m, n); return logTimeOut(k + m + n) }
首先用Promise
实现
//promise实现 function doIt() { console.time("doIt"); // 第一步初始时间 const time1 = 200; stepOne(time1).then(time2 => { return stepTow(time1, time2).then(time3 => [time1, time2, time3]) }) .then(timeArr => { const [time1, time2, time3] = timeArr return stepThree(time1, time2, time3) }) .then(result => { console.log('总共计算用时', result); console.timeEnd('doIt') }) } doIt()
使用async awiat
:
// async await 实现 async function startIt() { console.time("startIt") const time1 = 200; const time2 = await stepOne(time1) const time3 = await stepTow(time1, time2) const result = await stepThree(time1, time2, time3) console.log('总共计算用时', result); console.timeEnd('startIt') }
打印结果:
这样对比就能明显看出区别Promise
实现的代码逻辑复杂,不清晰,不直观,而通过async await
,可以将异步逻辑,用类似于同步的代码实现,简洁明了
这是到目前为止的个人理解,转载请标明出处