V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
coolicer
V2EX  ›  Node.js

[讨论]ES6 generator 跟 promise 还是很大的区别,你们怎么看

  •  
  •   coolicer · 2014-09-24 10:34:47 +08:00 · 12581 次点击
    这是一个创建于 3747 天前的主题,其中的信息可能已经有所发展或是发生改变。
    promise看得出是在形式上避免了回调,generator感觉比较灵活,可以改变运行的顺序。promise有用过,generator没有。

    用过的人说说?
    第 1 条附言  ·  2014-09-24 11:40:35 +08:00
    为什么node的主题是纯黑,能正常点吗?
    13 条回复    2014-09-24 18:24:29 +08:00
    willwen
        1
    willwen  
       2014-09-24 10:58:43 +08:00 via iPhone   ❤️ 2
    作為國內來說還算少數的Harmony使用者,我可以說說自己的經驗。
    1. Promise經歷了好幾個版本的製定,從很久之前就已經存在,它解決的是串行的異步嵌套問題
    2. yield關鍵字把Generator Function切割為擁有多個出口的Generation

    Promise是JavaScript社區的研發產物,而yield則是ECMA-262從別處參考而來的「類協程」實現。

    yield可以做到非串行,而Promise很難。Promise兼容性強,yield只能繼續等。
    各有千秋

    關於Generation,請參考我的博客。http://lifemap.in/koa-co-and-coruntine/
    otakustay
        2
    otakustay  
       2014-09-24 11:17:46 +08:00   ❤️ 2
    本来就不是为了实现一个东西提出的……generator本质上不是解决异步的方案,让你们用来玩异步了而已啊,ES7的async才是真正做异步的
    coolicer
        3
    coolicer  
    OP
       2014-09-24 11:33:52 +08:00
    @willwen
    @otakustay
    受教了..
    coolicer
        4
    coolicer  
    OP
       2014-09-24 11:34:37 +08:00
    @willwen 原来前几天看的文章是你写的,刚看过。
    jsonline
        5
    jsonline  
       2014-09-24 11:35:13 +08:00
    Promise 哪里避免了回调?
    只是一种回调的规则而已。
    willwen
        6
    willwen  
       2014-09-24 11:35:37 +08:00 via iPhone
    @otakustay 灰大大麼麼噠
    coolicer
        7
    coolicer  
    OP
       2014-09-24 11:39:03 +08:00
    @jsonline 额,没说完整。避免了回调写法
    otakustay
        8
    otakustay  
       2014-09-24 11:55:46 +08:00   ❤️ 2
    Promise最大的特点有以下几个:

    1. 原本嵌套式的callback模型变成“看上去线性”的模型,以此提供代码逻辑的顺畅性
    2. 异常传递,即当任何一个Promise失败时,异常会透过那些没有reject处理的节点一直到最后去,这是NodeJS的callback模型没有做到的。异常传递更接近正常代码中的try/catch,你可以有N行代码,任何一行代码都可能出错,但总能被后面的catch捕获,而NodeJS的callback模型要在每个callback中处理err参数,这是我一直反对NodeJS的异步模型的很重要的原因之一

    而以上几点,其实通过Generator都能做,但这并不代表Generator和Promise是一类东西。Generator可以做更多的事,比如:

    1. 生成一个无限列表,每次获取都递增1
    2. 完成类似C#的Linq的工作,即多个对数组元素的操作(Iterator)只需要遍历一次数组,比如这样:asGenerator(array).each(o -> o.x++).where(o -> o.x > 10).map(o -> o.x),只有一次遍历
    3. 产生一个每次获取一个元素都有重要、高消耗的资源访问的列表,完成延迟加载模型来将高消耗的元素获取延迟到真正访问时,而不需要一开始就获取N次形成静态的数组

    Generator的用法非常非常多,上面说的也只是经典场景而已,绝对不要只把它当成一个coroutine的玩法,会被自己关在笼子里玩不开的
    zhyu
        9
    zhyu  
       2014-09-24 12:07:47 +08:00 via iPhone   ❤️ 1
    这俩不是一个东西啊(
    promise避免了回调的嵌套写法,代码可读性更好,异常处理也比较方便
    generator…我会说我看到的时候就想到我写python的时候了么(我python写的多,node还在摸索中
    otakustay
        10
    otakustay  
       2014-09-24 13:15:51 +08:00   ❤️ 1
    > 为什么node的主题是纯黑,能正常点吗?

    因为这里是为了黑Node而存在的(误
    SoloCompany
        11
    SoloCompany  
       2014-09-24 13:28:52 +08:00   ❤️ 1
    generator 是把一段看上去是同步执行的代码给「异步」起来,可以给你很好的控制代码运行的状态和行为,甚至可以具备达到让你用同步的方式来写异步代码的能力,但理解起来会有点困难。

    而 promise 就是个专门为异步设计的东西,是把异步串接起来,和同步运行基本上是背道而驰的。

    另外要注意一下,比如类似于 facebook 的那种注入 generator 框架是很不靠谱的,本质上是修改你的代码,把同步定义的函数变成一个 yield;问题在于它又不足够智能,经常会把一些不该异步化的函数也给改了,但是在运行过程中很难发现也很难调试,这些坑只要踩过一次你都会选择远离的。要用 generator 还是等 ECMA6 正式发布吧
    skyitachi
        12
    skyitachi  
       2014-09-24 17:13:52 +08:00   ❤️ 1
    generator 的特点在于lazy computation,结合es6的for...of会很方便很强大,当然这只是generator的基础用法。
    promise 在于让异步代码看上去同步化,有着更好的可读性。
    klam
        13
    klam  
       2014-09-24 18:24:29 +08:00   ❤️ 1
    深入理解Promise: http://segmentfault.com/blog/kk_470661/1190000000586666
    Node.js回调黑洞全解:Async、Promise 和 Generator: http://zhuanlan.zhihu.com/FrontendMagazine/19750470
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2753 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 00:05 · PVG 08:05 · LAX 16:05 · JFK 19:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.