手机网站弹窗/培训网站推荐
JS中调用 async 函数时会返回一个 Promise 对象(隐式转换)。当async 函数返回一个值时,Promise 的 resolve 方法会负责传递这个值,当 async 函数抛出异常时,Promise 的 reject 方法也会传递这个异常值。
在async 函数中如果遇见 await 表达式,则 async 函数会暂停执行,等待表达式中的 Promise 解析完成后继续执行 async 函数并返回结果。
基于上面的定义,我们来对比一下如下的代码,我们就知道优化点如何排查了。
function resolveAfter2Seconds(x) {return new Promise(resolve =>setTimeout(() => resolve(x), 2000))
}async function fn1(x) {var a = resolveAfter2Seconds(20)var b = resolveAfter2Seconds(30)return x + await a + await b
}// prints 60 after 2 seconds
fn1(10).then(v => console.log(v))async function fn2(x) {var a = await resolveAfter2Seconds(20)var b = await resolveAfter2Seconds(30)return x + a + b
}// prints 60 after 4 seconds
fn2(10).then(v => console.log(v))
上面的代码演示代码中,我们可以发现,不同的 await 位置声明,会直接影响到函数执行的时间。
同时,我们在处理 async 函数的返回时,针对其 reject 的场景时,try-catch 模块来进行捕获,但由于try-catch会创建独立的作用域(这算是很老的一个点了,不知新版的V8有没有进行过优化),所以会在性能上有一些损失,但是相对于代码的可读性,这一点损失也无所谓啦。
async function fn(url) {let vtry {v = await doSomething(url)} catch (e) {v = await handlerError(url)}return success(v)
}// 比价丑陋的写法,通过牺牲代码的可读性来避免作用域的开辟async function fn(url) {let vv = await doSomething(url).catch(err => {v = await handlerError(url)})return success(v);
}