You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
kaisa911, cnym, yishuihan-001, l0ng09, Clearives and 96 moreSimonTart, andypinet, liuliudaren, 2XI, yangtao0723 and 4 morejlh909943082, arashethis and 1xiaobaiyangtao0723, dmljc and HideerdmljcLarmyliu, tomsithome and benwei925
var a = 0
var b = () => {
var temp = a;
Promise.resolve(10)
.then((r) => {
a = temp + r;
})
.then(() => {
console.log('2', a)
})
}
b()
a++
console.log('1', a)
Activity
sisterAn commentedon Feb 16, 2019
JS 异步已经告一段落了,这里来一波小总结
1. 回调函数(callback)
缺点:回调地狱,不能用 try catch 捕获错误,不能 return
回调地狱的根本问题在于:
优点:解决了同步的问题(只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。)
2. Promise
Promise就是为了解决callback的问题而产生的。
Promise 实现了链式调用,也就是说每次 then 后返回的都是一个全新 Promise,如果我们在 then 中 return ,return 的结果会被 Promise.resolve() 包装
优点:解决了回调地狱的问题
缺点:无法取消 Promise ,错误需要通过回调函数来捕获
3. Generator
特点:可以控制函数的执行,可以配合 co 函数库使用
4. Async/await
async、await 是异步的终极解决方案
优点是:代码清晰,不用像 Promise 写一大堆 then 链,处理了回调地狱的问题
缺点:await 将异步代码改造成同步代码,如果多个异步操作没有依赖性而使用 await 会导致性能上的降低。
下面来看一个使用
await
的例子:对于以上代码你可能会有疑惑,让我来解释下原因
b
先执行,在执行到await 10
之前变量a
还是 0,因为await
内部实现了generator
,generator
会保留堆栈中东西,所以这时候a = 0
被保存了下来await
是异步操作,后来的表达式不返回Promise
的话,就会包装成Promise.reslove(返回值)
,然后会去执行函数外的同步代码a = 0 + 10
上述解释中提到了
await
内部实现了generator
,其实await
就是generator
加上Promise
的语法糖,且内部实现了自动执行generator
。如果你熟悉 co 的话,其实自己就可以实现这样的语法糖。本文首发于我的博客:JS异步解决方案的发展历程以及优缺点
inJs commentedon Mar 7, 2019
@sisterAn 没有依赖关系的异步操作不使用
await
就没有你所说的性能问题了。 比如:Zousdie commentedon Mar 7, 2019
@sisterAn 规范里好像没提到 await 内部实现了 generator, 如果从 polyfill 中的实现去断定 await 内部就是 generator……这样好像有点不严谨……
另外
await
的例子其实可以转换为duanzheng commentedon Mar 27, 2019
请教一下,为何 b 里不是直接访问 a?
[-]第十二题[/-][+]第 12 题:JS 异步解决方案的发展历程以及优缺点。[/+]Randysheng commentedon May 23, 2019
@duanzheng
若 b 里直接访问 a ,即写为
a = a + r
,则最后then打印'a' 11
,因为会先执行a++
。我猜他应该是为了保持最后的打印结果是'a' 10
,所以才使用了一个变量缓存最初a的值吧。个人见解michaelcai commentedon Jul 10, 2019
其实提到了 Promise.al 就说明这里有个隐含前提,尽管三个 fetch 之前没有依赖,但是需要等待三个 fetch 都已经完成了再执行下一句。
arixse commentedon Jul 10, 2019
callback->Promise->generator->async/await
NuoHui commentedon Jul 22, 2019
需要好好理解的是async, await VS Generator改进了什么
lk3407105 commentedon Jul 23, 2019
Promise 如果在这样写
Promise.resolve().then(function() { return new Promise(function() {}) })
这样写的话Promise就可以中止Promise执行链,相当于取消Promise了
252860883 commentedon Aug 21, 2019
我尝试以下代码片段,按照您这样模拟是行不通的,不太理解为什么我这样写async里面输出就是 11:
eightHundreds commentedon Aug 22, 2019
kt3721 commentedon Sep 4, 2019
上面说了执行到 await 的时候会保留 堆栈中的东西,这个时候变量a并没有使用,所以并没有保留 a = 0;当 await 结束后,再使用变量a,此时a的值经过 a++ 已经变成了 1 了。所以最后输出的是11。
24 remaining items