【问题标题】:Native Support for Promises in Node.jsNode.js 中对 Promise 的原生支持
【发布时间】:2016-01-10 14:31:47
【问题描述】:

当前版本的 Node.js 是否对 Promise 提供原生支持?

Node.js 使用 V8 引擎。 Chrome 也使用了这个 JavaScript 引擎,Chrome 32 原生支持 Promise。但我似乎无法获得在 Node.js 中(本地)工作的承诺。

我已经在 Chrome 32 中尝试了以下代码,它可以工作。

var promise = new Promise(function(resolve, reject) {
  // do a thing, possibly async, then…

  if ( 1===1 /* everything turned out fine */) {
    resolve("Stuff worked!");
  }
  else {
    reject(Error("It broke"));
  }
});

promise.then(function( message ) {
  console.log( message );
},
function( err ) {
  console.log( err );
});

但是,当我在 Node.js 中尝试相同的代码时,我得到:

var promise = new Promise(function(resolve, reject) {
                   ^
ReferenceError: Promise is not defined

这段代码来自优秀的教程:

http://www.html5rocks.com/en/tutorials/es6/promises/

【问题讨论】:

  • Node 中的本机支持在所有模块都开始使用它之前并不是很有用。承诺一切。
  • @StevenLu:点击你的链接后我读到的第一件事:BEWARE This article is old, it's 2013 old. Since then things have changed and a winner has prevailed, Bluebird is a Promises Library build with performance in mind and when actually tested with the benchmarks of this article it did even better than Async!
  • 请大家注意,Bluebird 声称是最快的已经有好几年了,它的速度声称基本上只是一个短路边缘情况,每次我亲自测试它时,它都有显然不是最快的。我个人使用 when.js 是因为它有很多让我的生活更轻松的功能,但碰巧的是,每次我进行性能比较时,它总是比 Bluebird 和 kew 快一点。唯一可以称为“慢”的库是 Q,它已经 4 年没有更新了。如果您选择速度,请先自己测试!

标签: javascript node.js promise


【解决方案1】:

虽然 Node.js 在稳定版中添加了原生承诺 0.12

但由于内存泄漏问题,我建议使用bluebird 来避免该问题。


老答案:

Node.js 自版本 0.11.13 起添加了原生 Promise 支持。

nvm install 0.11.12
nvm run 0.11.12
> Promise
ReferenceError: Promise is not defined
> console.log(process.versions.v8)
3.22.24.19

nvm install 0.11.13
nvm run 0.11.13
> Promise
[Function: Promise]
> console.log(process.versions.v8)
3.25.30

注意:Node.js v0.11 仍处于测试阶段,如果在生产环境中使用,请小心。

【讨论】:

  • 有谁知道提到的内存泄漏在节点 4/5 中是否仍然存在问题?
  • 不幸的是,答案是肯定的。欲了解更多信息:github.com/nodejs/node/issues/4210.
  • @1nfiniti 不,Chris 链接的问题现已关闭
  • @JanusTroelsen 以及“关闭,因为它现在不是一个可操作的问题。”听起来不像是固定的……
  • @LJᛃ 最新评论现在说“修复已于去年登陆 V8 master,所以我认为它现在应该已经登陆 Node”
【解决方案2】:

我知道自从 OP 发表这篇文章以来已经有很长时间了,但我想更新那些仍在设法通过搜索找到这个问题的人。

Node.js 添加了对 Promises 的原生支持,因为它与 io.js 合并。这发生在 2015 年 9 月 8 日(根据 Node.js 官方网站上的 this 新闻发布),这是 Node v4.0.0 的第一个稳定版本。

第 4 版中添加了许多新的 ES6 功能,例如 Promises。您可以阅读有关它们的更多信息here

编辑:值得注意的是,it appears as though Bluebird's Promise performs better than the native implementation of Promise

【讨论】:

    【解决方案3】:

    重要的是要指出,这个问题的公认答案是使用一个 Promise 库,该库在语法上与 Promises/A+ 规范定义的原生 JS Promise 功能不同。

    如果您希望 Node 尽可能地模仿浏览器,那么您应该使用位于 https://github.com/jakearchibald/es6-promisees6-promise 模块。

    npm install es6-promise

    var Promise = require("es6-promise").Promise

    技术差异:

    模块的一个关键区别在于构造函数:var foo = new Promise() 在您的浏览器中无效,因为Promise 构造函数需要一个函数来初始化,该函数将负责解析或拒绝该承诺。在node-promises 模块中,Promise 的所有用户都可以访问 resolve,这打破了 Promise 的封装。

    使用node-promises 的示例

    var foo = new Promise() 
    // no encapsulation, now anyone you pass this promise to can resolve it with whatever they want.
    

    使用es6-promises的示例

    var foo = new Promise(function(resolve, reject) { resolve("foo") }) 
    // encapsulation, no one is able to resolve this Promise but the originator of that Promise.
    

    如果您希望能够公开公开解决/拒绝功能,则需要展开承诺,例如 here

    【讨论】:

    • 阅读您的帖子后,我决定尝试 es6-promise,但在安装 es6-promises 时遇到了一些问题,因为这就是您在最后一个代码之前所说的样本。以为我会提到它,以防其他人做同样的事情。
    • 这个答案现在已经过时了
    • 正如 LJ 提到的,问题已关闭,但看起来并没有解决,所以我认为答案没有过时
    【解决方案4】:

    如果 node 使用的 V8 版本与 Chrome 32 使用的相同或更高版本,那么它很可能是本机支持的。否则你需要加载'es6-shim'(我建议先加载es5-shim)我不知道当前版本的node使用的是哪个版本的V8。

    在我的节点上安装

    node --version
    v0.10.24
    
    node -e 'console.log(process.versions.v8);'
    3.14.5.9
    

    Chrome V32 使用的是什么版本? (我使用的是 Chromium v​​27),所以必须找到文档,但可能是 3.22.24.16

    查看chrome://version/ 似乎可以提供信息

    Chromium    27.0.1453.93 (Developer Build 200836) Built from source for Fedora release 19 (Schrödinger’s Cat)
    OS  Linux 
    WebKit  537.36 (Unknown URL@0)
    JavaScript  V8 3.17.6.14
    Flash   11.2 r202
    User Agent  Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36
    Command Line     /usr/lib64/chromium-browser/chromium-browser --enable-plugins --enable-extensions --enable-user-scripts --enable-printing --enable-sync --auto-ssl-client-auth --flag-switches-begin --enable-sync-favicons --enable-full-history-sync --sync-keystore-encryption --flag-switches-end
    Executable Path /usr/lib64/chromium-browser/chromium-browser
    Profile Path    /home/graham/.config/chromium/Profile 1
    Variations  b03ddc1f-2d9ef0cc
    f9b252d0-fd526c81
    ff3fc1a6-766fa2d
    7f6da4bf-70d6abf1
    75f7fb7e-611a9f49
    262f996f-42d3ce07
    24dca50e-455c9cca
    ca65a9fe-91ac3782
    3028188e-626278e
    5e29d81-cf4f6ead
    246fb659-6754d7b7
    f296190c-72d8285f
    4442aae2-4ad60575
    75f0f0a0-a5822863
    e2b18481-6e3b1976
    e7e71889-e1cc0f14
    

    现在从 Chrome 安装

    Google Chrome   32.0.1700.107 (Official Build 248368) 
    OS  Linux 
    Blink   537.36 (@165586)
    JavaScript  V8 3.22.24.17
    Flash   12.0.0.44
    User Agent  Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36
    Command Line     /usr/bin/google-chrome-stable --flag-switches-begin --flag-switches-end
    Executable Path /opt/google/chrome/google-chrome
    Profile Path    /home/graham/.config/google-chrome/Default
    Variations  b178bdde-887f97ea
    24dca50e-837c4893
    8d790604-9cb2a91c
    5a3c10b5-e1cc0f14
    244ca1ac-4ad60575
    5e29d81-cf4f6ead
    3ac60855-486e2a9c
    246fb659-bd104136
    f296190c-38939ee9
    4442aae2-6e597ede
    ed1d377-e1cc0f14
    75f0f0a0-e1cc0f14
    e2b18481-6e597ede
    e7e71889-4ad60575
    

    【讨论】:

    • 在Windows(10)命令行中,Node版本检查需要用双引号括起来,即node -e "console.log(process.versions.v8)"
    【解决方案5】:

    我尝试了带有 --harmony 标志的 Node v0.11.12,但它没有原生承诺。

    带有 --harmony 标志的 v0.11.13 及更高版本确实具有 Promise。

    【讨论】:

      【解决方案6】:

      你需要有最新的 V8 版本 - 尝试从 master 分支编译 - 你会发现 V8 版本 3.25.30 和 Promises

      与标准 Q 的快速比较:

      Q>resolve>then 100k times:
      real    0m7.459s
      user    0m7.121s
      sys     0m0.346s
      
      V8 Promose>resolve>then 100k times:
      real    0m0.980s
      user    0m0.884s
      sys     0m0.097s
      

      【讨论】:

        【解决方案7】:

        看起来 v0.12 支持 Promise,见 node.Promise

        【讨论】:

        • 嗯,那是 v0。 1.12 - 从 2011 年开始!从我在那里读到的内容,这些“承诺”甚至都无法实现。
        • 哦,废话!是的,v0.1.12 与 v0.12 有很大的不同。谢谢你纠正我。那么,缺乏承诺支持是推动IO.js 起义的部分原因吗?我自己,现在,我只使用Q
        【解决方案8】:

        虽然 Promise 不是原生在 node.js 中(还)。 node.js 的IO.js fork 原生拥有它们。看: http://davidwalsh.name/es6-io

        【讨论】:

          猜你喜欢
          • 2016-01-20
          • 1970-01-01
          • 2011-04-03
          • 2020-02-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-28
          • 1970-01-01
          相关资源
          最近更新 更多