请解释babel编译后的async原理
1 2 3 4 5 6 7
| let a = 0; let yideng = async () => { a = a + await 10; console.log(a) // 10 } yideng(); console.log(++a); // 1
|
async/await
在async/await之前,我们有三种方式写异步代码:
嵌套回调
以Promise为主的链式回调
使用Generators
async特点
async/await更加语义化,async 是“异步”的简写,async function 用于申明一个 function 是异步的;await,可以认为是async wait的简写, 用于等待一个异步方法执行完成;
async/await是一个用同步思维解决异步问题的方案(等结果出来之后,代码才会继续往下执行)
可以通过多层async function的同步写法代替传统的callback嵌套
async function语法
1 2 3 4 5
| async function name([param[, param[, ... param]]]) { statements } name: 函数名称。 param: 要传递给函数的参数的名称 statements: 函数体语句。 返回值: 返回的Promise对象会以async function的返回值进行解析,或者以该函数抛出的异常进行回绝。
|
await语法
1 2 3
| [return_value] = await expression; expression: 一个 Promise 对象或者任何要等待的值。 返回值:返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身。
|
错误处理
在async函数里,无论是Promise reject的数据还是逻辑报错,都会被默默吞掉,所以最好把await放入try{}catch{}中,catch能够捕捉到Promise对象rejected的数据或者抛出的异常。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(() => {reject('error')}, ms); //reject模拟出错,返回error }); }
async function asyncPrint(ms) { try { console.log('start'); await timeout(ms); //这里返回了错 console.log('end'); //所以这句代码不会被执行了 } catch(err) { console.log(err); //这里捕捉到错误error } } asyncPrint(1000);
|
如果不用try/catch的话,也可以像下面这样处理错误(因为async函数执行后返回一个promise)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(() => {reject('error')}, ms); //reject模拟出错,返回error }); }
async function asyncPrint(ms) { console.log('start'); await timeout(ms) console.log('end'); //这句代码不会被执行了 }
asyncPrint(1000).catch(err => { console.log(err); // 从这里捕捉到错误 });
|
使用场景
多个await命令的异步操作,如果不存在依赖关系(后面的await不依赖前一个await返回的结果),用Promise.all()让它们同时触发
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| function test1 () { return new Promise((resolve, reject) => { setTimeout(() => { resolve(1) }, 1000) }) }
function test2 () { return new Promise((resolve, reject) => { setTimeout(() => { resolve(2) }, 2000) }) }
async function exc1 () { console.log('exc1 start:',Date.now()) let res1 = await test1(); let res2 = await test2(); // 不依赖 res1 的值 console.log('exc1 end:', Date.now()) }
async function exc2 () { console.log('exc2 start:',Date.now()) let [res1, res2] = await Promise.all([test1(), test2()]) console.log('exc2 end:', Date.now()) }
exc1(); exc2();
|
例题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| async function async1(){ console.log(1) // 1 await async2(); console.log(3) // 3 } async function async2(){ console.log(2) } async1(); // 2 console.log(4) // 4
解析:
优先执行 console.log(1); await async2() 执行函数 存在立即执行内容 console.log(2) 强制等待... 执行console.log(4) 继续执行console.log(3)
|
任何值得做的事就值得把它做好。- Whatever is worth doing is worth doing well.