-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
精读《async/await 是把双刃剑》 #82
Comments
@popomore 来,吐槽下。 |
代码写成这样,只能怪自己学艺不精吧? a(() => {
b();
});
c(() => {
d();
}); 等价的应该是 await Promise.all(a().then(b), c().then(d)); 回调的问题在于,它必须是嵌套的。而async和await可以在一定程度上把异步代码写的像是同步的,从而达到更好的可读性。 |
@Ariex 用 .then 确实会简化点 |
@ascoders 并不是用 |
@Ariex 说的有一定道理,但是你能写好,其他人呢。? 希望能减少一些矫枉过正的评论,让其他读者可以平静的看到滥用带来的问题,不要陷入无谓的争斗。 |
各一朵小红花。 还没写完,也还没来得及翻译,当做基础用于将来分享,请批评。 |
@Ariex 对于一个刚开始接触async/await的前端小白来说,确实缺少一些成功的范例来引导《如何正确的使用async/await》,如果一个老手已经学会了轻车熟路,逃避async/await的陷阱,不妨来 一篇/几语 来指引一下。 |
@atian25 文中的例子是有意而为的,因为 callback 和 async/await 都经常出现在业务代码中,而业务项目又经常在倒排,有时候项目室热起来,内心一急躁,就写出连珠炮的 await。。 |
还是举个稍微正常一点的例子吧,文中的 a b c 这样的太简陋了,如果能举一个带有含义的单词,并举出存在以下的场景,再来讨论会更有聚焦一点
|
这篇文章的解读的前半部分使用到了英文原文的例子,后半部分采用了简化版的抽象例子。 |
用户详情页,根据用户 id 拿用户信息、历史文章列表、最近更新的文章列表;同时加载第三方问答插件,加载完毕后上报插件展现打点日志。 如果回调的方式写,是这样的: getUser(123, user => {
getArticles(user, articles => /* fresh view */)
getRecentArticles(user, articles => /* fresh view */)
})
initQA(() => {
reportQAPV()
}) 换成 promise: Promise.all([
getUser().then(user => {
getArticles(user).then(/* fresh view */)
getRecentArticles(user).then(/* fresh view */)
}),
initQA().then(reportQAPV)
]) 如果换成 async/await,最好拆两个函数: async getUserInfo() {
// 这里也要用到 .then,如果纯粹用 await 的话,这里代码会更多
getArticles(user).then(/* fresh view */)
getRecentArticles(user).then(/* fresh view */)
}
async initAndReportQA() {
await initQA()
reportQAPV()
}
async function main() {
await getUserInfo()
initAndReportQA()
} 如果写代码的时候比较急躁,可能会想在一个函数里快速完成任务: const user = await getUser()
getArticles(user)
getArticles(user).then(/* fresh view */)
await initQA()
reportQAPV() 这样 initQA() 就滞后了。 |
@xpal7512 如果用 callback 方式,就算写的急躁,顶多是不雅观,而不会出现性能问题。 |
不能因为 async/await 太易使用而怪罪它啊。成串的 await 使用本就意味着类似同步顺序一个个执行,如果需要考虑并发那就不能这么写,更多是因为人没有意识。 |
@ascoders 会不会出现性能问题我不知道,但写的急躁的话, callback 比 await 出现的 bug 的概率大,维护成本和 Review 成本也大。 你举得那个例子其实是偏袒 callback 了, getUser(123, user => {
getArticles(user, articles => /* fresh view */)
getRecentArticles(user, articles => /* fresh view */)
}) 实际情况下,这里 callback 还要处理异步协同,还有错误处理 PS:上面的示例代码,Promise 那块漏了 return,会坑死的 |
@atian25 async/await 相比 callback,项目整体更容易维护了,但局部代码执行性能可能比 callback 糟糕,原文说的 hell 应该指局部的问题。 |
其实我 diss 的是生造的 说到底就是 JS 这块的异步协同的锅,callback 是十八层地狱,Promise 和 await 是往上爬了 10 层,大幅解决了很多问题了,帮开发者省了很多事了,剩下的几层目前就是开发者本身的能力要求了。 但这个标题给人的印象是,刚爬出 callback hell,又掉入了隔壁另一个十八层地狱。 |
@atian25 确实是这样,很多同事第一眼看到这个标题就是这种感觉 |
我意识到 async/await 的问题没有那么严重,把文章标题改为 《async/await 是把双刃剑》。 |
我感觉应该是 「async/await 万里长征,还在路上」,「async/await 需要注意的点」,哈哈 说到底就是开发者还不熟悉 await,等了解后就没这些问题了 |
说到底就是开发者还不熟悉 await,等了解后就没这些问题了,我们日常开发就没看到有这类问题的讨论。 更多的是从 co 时代迁移过来后,一些不习惯的问题,如 还有就是 Promise 本身的那一堆坑,你看朴老师内网的分享,内存泄露的,一大半是 SSR,另一大半是 Promise 。 |
@atian25 好嘞,内网 ssr 内存泄漏的经典案例也略有耳闻,对于熟悉 node 的团队,对 js 特性都是一步步跟着过来的,有坑也先踩在 generator 上了。。 |
大概有些人为了逼格而用上async/await,却没有去思考它实际怎么运作。 |
就像那些一直翘首以盼 |
callback -> fibers.js -> promise -> generator + co.js -> async/await 这个演进过程,一直也就只是语法糖的改变而已 说到底也就是开发者,没分清楚什么时候要并发执行,什么时候要串行执行 这个问题和场景,最容易出现在哪? 就是出现在新手,在连异步并发都不知道是什么的情况下,跳过callback直接用async/await,他连自己想要什么样的执行顺序都不知道。 我的结论是,写例子的人,连自己想要什么样的执行顺序都不知道,和用callback和还是用async/await无关 |
async/await不是双刃剑,异步才是双刃剑 |
@CoderIvan 赞同。这不是 async/await 的问题,而是文章作者自己的问题,抱怨锤子不能当螺丝刀用。 |
这个问题已经讨论的很充分了。不是 async/await 不好,而是不理解就使用它会造成问题,这个看似简单的 api,其实对理解要求比较高,不要小看它。 |
如果把写代码急躁也算因素,那就算是 var 也可以写一篇滥用不好的文章出来。 |
如果代码写得急躁算是一个因素的话,那么使用回调还大概率会导致获取不到异步数据会得到undefined。 因为我们的思维基本都是同步思维。是JS以前只能写回调的形式,你写了几年代码,终于熟悉了回调的形式。 |
@zerofront 不是指回调代码比 async 更容易看懂。 指的是回调更容易写出正确顺序的异步代码,而 async 容易导致原本能并行的移步写成了串行。 |
这个例子中 getUserInfo 为什么是 async ? |
@abisuq 例子写的有问题,应该去掉 |
滥用回调才是地狱 |
文章例子对意图表达不清晰,此处的改造也不是太合适 await 的使用准则:仅在需要 promise 的内含资源前一刻时,才进行 await
async await 是为了让 异步编程 像 同步执行,这样可以获得一些好处
只要遵循:仅在需要 promise 的内含资源前一刻时,才进行await 就可以做到异步操作尽可能并行,而逻辑代码可以。类似浏览器,会充分并行下载内嵌资源,但默认按照script标签顺序执行 |
文章地址,前端的发展就是一个大逃亡,刚逃离了 callback 地狱,又要开始逃离 async/await 地狱。
The text was updated successfully, but these errors were encountered: