对 js 异步中的 promise、async 等的理解。

2019-12-23 17:55:00 +08:00
 vevlins

Promise 本质上还是 callback 机制,js 在原有的 task 队列外新增了 promise 的 job 队列,每次 eventloop 时先看 job 队列,清空后再看 task 队列。

generator 是 js 中的协程,在一个函数内标注 yield,遇到该段代码时保存函数执行上下文,跳出当前函数执行接下来的函数,手动 next 时再恢复到上一个保存的函数执行现场。 这样在做 io 操作时发出了系统调用后就保存住现场继续把 cpu 释放给其他代码块,等到调用完成拷贝到应用空间时再回来执行。

async、await 是利用 promise 对 generator 进行了封装,实现了自动 next,实质上就是 io 操作完成后的 callback 执行了 next。

上述理解对吗?

4108 次点击
所在节点    JavaScript
9 条回复
fpure
2019-12-23 18:02:48 +08:00
mark 下,等高手解答
YuTengjing
2019-12-23 18:43:29 +08:00
可以用 promise 和 generator 来实现 await 但是不能说 async 和 await 本质就是对 promise 和 generator 封装,V8 貌似早就原生支持了 await,原生支持和模拟的还是不一样的。Tj 大神的 co 库其实功能就类似于 async/await。其实手动实现简化版的 promise 和 async/await 也不是很难: https://github.com/tjx666/javascript-code-lab。
IWSR
2019-12-23 19:29:41 +08:00
qqjay2019
2019-12-23 19:29:52 +08:00
每个 Promise 有一个状态(等待态,成功态,失败态),有成功的结果和失败的结果,有成功的回调数组和失败的回调数组.

new Promise(fn)一执行,fn(resolve,reject)就会执行.然后改变状态,并且往相应的回调数组里面 push

一旦 then,就 return new Promise()实现链式调用

如果是异步代码的话,到 then 时候,状态还是 pengding,往成功和失败回调 push 一个时间为 0 的 setTimeout,然后开始真正处理 promise..后面还挺麻烦的讲不清楚

https://pro 删 mises 除 aplus.我 com/ 就算这个网站的 2.3,针对各种情况,有不同的处理方式,2.2 讲了 then

可能打字表达不太清楚... -T T-
IWSR
2019-12-23 19:31:20 +08:00
@IWSR 只要能把它卡住 其实 generator 还是 while 都可以
hoyixi
2019-12-23 20:17:05 +08:00
个人理解:语法糖,使得写 callback or generator 的体验更好,仅此而已。

那些长篇大论分析这俩的,尤其中文抄来抄去的文章,最好别看,浪费时间,还越扯越复杂,不知扯到哪里去了。
autoxbc
2019-12-23 20:39:01 +08:00
异步是一种编程无关的,自然存在的,事件处理流程
所有异步组织形式的本质都是异步,并不互相为本质

callback,promise,async 是三种异步代码组织形式
按顺序分别为 嵌套式,链式,扁平式
不同形式可以互相转化,没有什么区别

扁平式的优点,仅仅是因为比较适合人类读写,对机器没分别
有精力可以研究互相转化的细节,但不要被细节所困扰
secondwtq
2019-12-24 01:30:36 +08:00
解决问题有 top-down 和 bottom-up 两种方式,你说"理解",你是想要 top-down 的理解,还是要 bottom-up 的理解?

从完全 bottom-up 的角度,这些东西都可以理解为“一切最后都变成 callback”,这种过度的 Reductionism 对真正理解问题无益,同样的现象发生于“一切编程语言的‘本质’都是汇编”和 #6 的“一切语法都是语法糖”等言论上。
从完全 top-down 的角度,则可以说“一切都是异步”,这同样对理解问题无益(至少没有突出各项之间的区别)。
我见过很多人在看问题时过度强调其中一方面而忽视另一方面,导致“理解”出现障碍。尤其是遇到新东西的时候。

楼主说的“Promise 本质上还是 callback 机制”这就是从 bottom-up (实现)的角度看问题,并且将其单方面地作为”本质“,比较中立的说法是:”“Promise 主要利用 callback 机制实现“。

从 bottom-up 的角度,V8 的 native implementation 确实是使用的 generator 封装 async/await (其他 JS 引擎应该也差不多);而从 top-down 的角度,使用者无需关心 async/await 是如何实现的(但是我猜标准可能就把 generator 和 async/await 两者绑到一块了)。
vevlins
2019-12-24 13:20:30 +08:00
再补充一下,其实我想说的 callback 机制是 js 中的 eventloop,而非 cps 之类的概念。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/631599

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX