对 js 异步中的 promise、async 等的理解。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
vevlins
V2EX    Javascript

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

  •  
  •   vevlins 2019-12-23 17:55:00 +08:00 4541 次点击
    这是一个创建于 2120 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    上述理解对吗?

    9 条回复    2019-12-24 13:20:30 +08:00
    fpure
        1
    fpure  
       2019-12-23 18:02:48 +08:00
    mark 下,等高手解答
    YuTengjing
        2
    YuTengjing  
       2019-12-23 18:43:29 +08:00   3
    可以用 promise 和 generator 来实现 await 但是不能说 async 和 await 本质就是对 promise 和 generator 封装,V8 貌似早就原生支持了 await,原生支持和模拟的还是不一样的。Tj 大神的 co 库其实功能就类似于 async/await。其实手动实现简化版的 promise 和 async/await 也不是很难: https://github.com/tjx666/Javascript-code-lab。
    IWSR
        3
    IWSR  
       2019-12-23 19:29:41 +08:00   1
    qqjay2019
        4
    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
        5
    IWSR  
       2019-12-23 19:31:20 +08:00
    @IWSR 只要能把它卡住 其实 generator 还是 while 都可以
    hoyixi
        6
    hoyixi  
       2019-12-23 20:17:05 +08:00   1
    个人理解:语法糖,使得写 callback or generator 的体验更好,仅此而已。

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

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

    扁平式的优点,仅仅是因为比较适合人类读写,对机器没分别
    有精力可以研究互相转化的细节,但不要被细节所困扰
    secondwtq
        8
    secondwtq  
       2019-12-24 01:30:36 +08:00   1
    解决问题有 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
        9
    vevlins  
    OP
       2019-12-24 13:20:30 +08:00
    再补充一下,其实我想说的 callback 机制是 js 中的 eventloop,而非 cps 之类的概念。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5581 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 01:32 PVG 09:32 LAX 18:32 JFK 21:32
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86