async/await
Posted 前端菜鸡儿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了async/await相关的知识,希望对你有一定的参考价值。
async await
我们直接进入主题!!!
1.async和await是什么?
async:
是ES7语法,用于声明一个function是异步函数。
await:
等待一个异步方法完成。
ps:await只能出现在async函数中,不然会报错,如示例1-1;
Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules
Await只在异步函数和顶级模块体中有效.
1 /*示例 1-1*/ 2 let fun = function (){ 3 console.log(\'错误示例\'); 4 } 5 await fun(); 6 7 let fun1 = function(){ 8 console.log(\'正确示例\'); 9 } 10 let fun =async function (){ 11 await fun1(); 12 } 13 fun();
2.async到底干了什么? (一): 我们先看一下async声明的函数,返回值到底是个什么。 ps:如示例2-1; 可以看到返回的其实就是一个promise对象。Promise {<fulfilled>: "async"} 所以,async直接返回一个promise对象。如果在函数中直接return一个直接量,async会通过promise.resolve()封装成promise对象。 ps:Promise.resolve(e)可以看作是 new Promise(resolve => resplve(e))的简写,可以快速将字面量对象或其他对象分装成promise实例。 (二): 使用async不用await可以处理返回值吗? ps:如示例2-2-1; 如示例2-2-2,async声明的函数是一个promise对象,所以我们当然可以用then()链去处理。 (三): 到这里就会产生一个疑问,既然async返回是一个promise对象,并且promise的特点就是无等待,在没有await的情况下会立即执行,不会阻塞后面的语句,和普通的promise并无二致, 我们为什么要用async和await呢? 我们看示例2-3-1,模拟了一个异步操作,因为promise并不会造成阻塞,所以打印2输出为null,打印1会在一秒以后输出111, 想一个问题如果我们有的代码是基于异步完成之后的结果,要怎么处理?对,我们可以在then()函数中写,如果有多个promise并且相互依赖呢?
1 /*示例2-1*/ 2 3 let fun = async function(){ 4 return \'async\'; 5 } 6 console.log(fun());//Promise {<fulfilled>: "async"} 7 8 /*示例2-2-1*/ 9 fun().then(e=>{ 10 console.log(e);//async 11 }) 12 13 /*示例2-3-1*/ 14 var param = null; 15 16 let fun = () => { 17 return new Promise(resolve => { 18 setTimeout(() => resolve(function(){ 19 param = \'111\'; 20 }), 1000); 21 }); 22 } 23 24 fun().then(v => { 25 v(); 26 console.log(param,\'1\'); 27 }); 28 console.log(param,\'2\');
3.await到底在等什么? (一): 官方介绍,await等待的是一个promise对象或者是其它值。 实际await等待的是一个返回值,所以await后边可以接普通函数,或者是直接量。 ps:如示例3-1-1。 (二): await等到了要等的东西,然后呢? await是一个运算符,用于组成表达式,await表达式的运算结果取决于等到的东西。 如果await等到的不是一个promise对象,那await运算结果就是等到的东西。 如果await等到的是一个promise对象,那会阻塞后面的代码,等着promise对象resolve,然后得到resolve的值,最为await运算结果。 注意: 阻塞,只是async把所有的阻塞都封装在一个promise对象中异步执行,这也是await必须使用在async函数中的原因。 ps:如示例3-2-1。 示例会先执行打印3 输出null,然后一秒以后异步结束执行1,2。
1 /*示例3-1-1*/ 2 let fun = function () { 3 return "fun"; 4 } 5 6 let asyncFun = async function () { 7 return Promise.resolve("asyncFun"); 8 } 9 10 async function test() { 11 const v1 = await fun(); 12 const v2 = await asyncFun(); 13 console.log(v1, v2); 14 } 15 16 test(); 17 /*示例3-2-1*/ 18 var param = null; 19 20 let fun = () => { 21 return new Promise(resolve => { 22 setTimeout(() => resolve(function () { 23 param = \'111\'; 24 }), 1000); 25 }); 26 } 27 28 let awaitFun = async function () { 29 await fun().then(v => { 30 v(); 31 console.log(param, \'1\'); 32 }); 33 console.log(param, \'2\'); 34 } 35 awaitFun(); 36 console.log(param, \'3\');
4.目前看来使用Promise和async,await好像并没有什么区别? (一): 我们简单做一个比较。 不用async/await: ps:示例4-1-1。 使用async/await: ps:示例4-1-2。 好,我们发现好像并没有什么区别?so,优势到底在哪里? (二): async/await优势: 其实单一的promise并不能发现async/await优势,但是如果处理多个优势就出来了。 说白了async/await好像就是用来优化promise。 现在,我们假设一个业务,分成多步,且每一步都依赖于上一步的结果。 ps:示例4-2-1。 有没有发现什么??? 在看一个,把业务要求改一下,仍然是三个步骤,但每一个步骤都需要之前每个步骤的结果。 ps:示例4-2-2。 哇,是不是很神奇!!!
1 /*示例4-1-1*/ 2 let fun = function () { 3 return new Promise(resolve => { 4 setTimeout(() => resolve("not async/await!!!"), 1000); 5 }); 6 } 7 8 fun().then(v => { 9 console.log("async", v); 10 }); 11 /*示例4-1-2*/ 12 let fun = function () { 13 return new Promise(resolve => { 14 setTimeout(() => resolve("is async/await!!!"), 1000); 15 }); 16 } 17 18 async function test() { 19 const v = await fun(); 20 console.log(v); 21 } 22 23 test(); 24 25 /*示例4-2-1*/ 26 /** 27 * 传入参数 n,表示这个函数执行的时间(毫秒) 28 * 执行的结果是 n + 200,这个值将用于下一步骤 29 */ 30 function getTime(n) { 31 return new Promise(resolve => { 32 setTimeout(() => resolve(n + 200), n); 33 }); 34 } 35 36 function step1(n) { 37 console.log(`step1 with ${n}`); 38 return getTime(n); 39 } 40 41 function step2(n) { 42 console.log(`step2 with ${n}`); 43 return getTime(n); 44 } 45 46 function step3(n) { 47 console.log(`step3 with ${n}`); 48 return getTime(n); 49 } 50 /*promise实现*/ 51 function doIt() { 52 console.time("doIt"); 53 const time1 = 300; 54 step1(time1) 55 .then(time2 => step2(time2)) 56 .then(time3 => step3(time3)) 57 .then(result => { 58 console.log(`result is ${result}`); 59 console.timeEnd("doIt"); 60 }); 61 } 62 63 doIt(); 64 /*async/await实现*/ 65 async function doIt() { 66 console.time("doIt"); 67 const time1 = 300; 68 const time2 = await step1(time1); 69 const time3 = await step2(time2); 70 const result = await step3(time3); 71 console.log(`result is ${result}`); 72 console.timeEnd("doIt"); 73 } 74 75 doIt(); 76 77 /*4-2-2*/ 78 function step1(n) { 79 console.log(`step1 with ${n}`); 80 return getTime(n); 81 } 82 83 function step2(m, n) { 84 console.log(`step2 with ${m} and ${n}`); 85 return getTime(m + n); 86 } 87 88 function step3(k, m, n) { 89 console.log(`step3 with ${k}, ${m} and ${n}`); 90 return getTime(k + m + n); 91 } 92 /*async/await实现*/ 93 async function doIt() { 94 console.time("doIt"); 95 const time1 = 300; 96 const time2 = await step1(time1); 97 const time3 = await step2(time1, time2); 98 const result = await step3(time1, time2, time3); 99 console.log(`result is ${result}`); 100 console.timeEnd("doIt"); 101 } 102 103 doIt(); 104 105 /*promise实现*/ 106 function doIt() { 107 console.time("doIt"); 108 const time1 = 300; 109 step1(time1) 110 .then(time2 => { 111 return step2(time1, time2) 112 .then(time3 => [time1, time2, time3]); 113 }) 114 .then(times => { 115 const [time1, time2, time3] = times; 116 return step3(time1, time2, time3); 117 }) 118 .then(result => { 119 console.log(`result is ${result}`); 120 console.timeEnd("doIt"); 121 }); 122 } 123 124 doIt();
5.总结 个人理解async/await是用来解决同步异步,更重要的是优化了promise。
ok,到此结束,后续会把实际应用场景更新进来,欢迎指出毛病哦!
以上是关于async/await的主要内容,如果未能解决你的问题,请参考以下文章