对Node.js中的Promises的本地支持


76

当前版本的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/zh-CN/tutorials/es6/promises/


1
直到所有模块都开始使用Node时,Node的本机支持才有用。承诺一切。
鲁迪2014年


6
@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!
Trevor

6
请大家注意,蓝鸟声称最快的速度已经有多年历史了,它的速度声称本质上只是一个短路情况,而且每次我亲自测试时,它显然都不是最快的。我个人使用when.js是因为它具有许多使我的生活更轻松的功能,但是碰巧每次我进行性能比较时,它总是比Bluebird和kew快一点。您可以称为“慢速”的唯一库是Q,并且它在4年内没有更新。如果您选择提高速度,请先自己测试!
安德鲁

Answers:


23

如果节点使用的是Chrome 32使用的相同或更高版本的V8,则很可能会自然支持它。否则,您将需要加载“ es6-shim”(我建议先加载es5-shim)。我不知道当前版本的节点正在使用哪个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)命令行中,节点版本检查需要用双引号引起来,即节点-e“ console.log(process.versions.v8)”
AndyS

55

尽管Node.js在稳定版本中添加了本机承诺0.12

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


旧答案:

自版本开始,Node.js添加了本机Promise支持0.11.13

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.jsv0.11仍处于测试阶段,如果在生产中使用它请小心。


2
有人知道节点4/5中提到的内存泄漏是否仍然存在吗?
1nfiniti '16

1
不幸的是,答案是肯定的。有关更多信息:github.com/nodejs/node/issues/4210
克里斯(Chris

@ 1nfiniti不,克里斯联系的问题现已关闭
Janus Troelsen

1
@JanusTroelsen很好“结束,因为现在这不是可行的问题。” 听起来不像是固定的……
LJᛃ16年

1
@LJᛃ最新评论现在说:“该修补程序去年已降落在V8主机中,所以我认为它现在应该已经降落在Node中”
Aur Saraf

43

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

由于Node.js与io.js合并,因此添加了对Promises的本机支持。这件事发生在2015年9月8日(按官方网站的Node.js新闻岗位)与节点V4.0.0的第一个稳定版本。

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

编辑:值得注意的是,似乎Bluebird的Promise的性能要优于Promise的本地实现


39

重要的是要指出,该问题的可接受答案使用的是Promise库,该库在语法上与Promises / A +规范中定义的本地JS Promise功能并不相同。

如果希望Node尽可能地模仿浏览器,则应使用es6-promise位于https://github.com/jakearchibald/es6-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.

如果您希望公开展示解决/拒绝功能,则需要兑现承诺,例如此处


通读您的文章后,我决定尝试使用es6-promise,但是在安装es6-promise s时遇到了一些问题,因为这就是您在上一个代码示例之前所说的。以为我会提到它,以防其他人做同样的事情。
汉森

这个答案现在已经过时了
Janus Troelsen

正如LJ所提到的,问题已经解决,但看起来并没有解决,所以我认为答案并不过时
ABCD.ca 2016年

6

我使用--harmony标志尝试了Node v0.11.12,它没有本机承诺。

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


3

您将需要拥有最新的V8版本-尝试从master分支进行编译-在那里您会发现带有Promises的V8版本3.25.30

与标准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

3

它看起来像v0.12支持承诺,请参阅node.Promise


2
嗯,那是v0。1 .12-从2011年开始!从我在那儿所读到的内容来看,那些“承诺”甚至是无法实现的。
Bergi

哎呀!是的,v0.1.12与v0.12有很大的不同。感谢您纠正我。那么,缺乏承诺支持是否会导致IO.js起义?我,现在,我只是用Q
Lonnie Best

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.