有关async/await
1. 新闻稿两个 async 方式
// 一般的函数新闻稿
async function foo(){}
//新闻稿两个函数函数
const foo = async function(){}
// async 方式的斜线函数const foo = async ()=>{}
2. async 的回到值
async 函数常常会回到两个 Promise 第一类假如 return URL前面并非两个 Promise,那么预设初始化 promise.resolve 方式展开切换async function asyncFunction (){
return Hello World
}
asyncFunction.then((data)=>{
console.log(data) // Hello World
})
下面的asyncFunction尽管回到了数组,却能用 then 方式来赢得最后值,这是外部将数组转化成了 Promise 的原故。
3. async 函数的执行过程
执行开始自动生成两个Promise执行中假如遇到return/throw 执行立刻退出假如遇到await 会暂停执行,但不会阻塞主线程,直到await前面的异步操作结束后恢复执行执行完毕无论是否使用 await,异步函数都会回到 Promise最佳实践
尽管async可以让代码看起来像同步代码,但是也不要错过了并行的机会,示例如下,wait 为异步代码,实际生产中可以是两个接口请求等操作。
bad : 最少1000毫秒执行完毕
async function series() {
await wait(500);
await wait(500); // 等待上两个异步结束后执行 return “done!”; // 累计耗时1000毫秒+
}
good : 最少500毫秒执行完毕
async function parallel() {
const wait1 = wait(500); // 执行异步
const wait2 = wait(500); // 执行异步
await wait1;
await wait2;
return “done!”; // 所有异步接受后 累计耗时500毫秒+
}
其他
不要为了await而await ,注意原本的代码业务逻辑,合理利用并行的情况。
比如有如下的异步代码(回调方式)
a(() => {
b();
});
c(() => {
d();
});
改用async 的方式, 假如写成
await a();
await b();
await c();
await d();
用回调再翻译回来就是
a(() => {
b(()=>{
c(()=>{
d()
})
});
});
偏离了原来的业务逻辑 ,变成了串行,继续优化async
const asyncA = a()
const asyncC = c()
await asyncA
b()
await asyncC
d()
尽管a和c 并行了,但是原本d只要c结束就可以执行,但是假如a的速度晚于c,就变成了
a(()=>{
d()
})
也就是d需要等待的时间为a和c的最大值,继续优化async,最后可以通过如下方式还原业务
(async () => {
await a()
b()
})()
(async () => {
await c()
d()
})()
异常捕获
一般情况可能会通过try catch 捕获,但是如下情况的异常是捕获不到的
async function catchDemo() {
try {
// 注意这里是return,并非await
return Promise.reject(new Error(“Oops!”));
} catch (error) {
// 代码不会执行到这里
}
}
catchDemo()
由于async运行的结果是回到两个Promise,所以可以通过.catch捕获
catchDemo().catch((error)=>{
console.log(error)
})
参考资料
https://zhuanlan.zhihu.com/p/36521539
https://www.freecodecamp.org/news/avoiding-the-async-await-hell-c77a0fb71c4c/
https://developers.google.com/web/fundamentals/primers/async-functions