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 · 3897 次点击
    这是一个创建于 1557 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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   ·   我们的愿景   ·   实用小工具   ·   1003 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 22:15 · PVG 06:15 · LAX 15:15 · JFK 18:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.