Native Support for Promises in Node.js
Asked Answered
O

8

79

Is there native support for promises in current versions of Node.js?

Node.js uses the V8 engine. This JavaScript engine is also used by Chrome, and Chrome 32 has native support for promises. But I can't seem to get promises to work (natively) in Node.js.

I've tried the following code in Chrome 32 and it works.

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 );
});

However, when I try this same code in Node.js, I get:

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

This code is from the excellent tutorial:

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

Obala answered 4/2, 2014 at 22:34 Comment(4)
Native support in Node isn't super useful until all the modules start using it. Promise all the things.Goodard
No! Do not promise things that often finish in a small fraction of a second.Doig
@StevenLu: The first thing I read after clicking your link: 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!Thorough
Please everyone be aware that Bluebird's claims to be the fastest is now years old, its speed-claims were essentially just a short-circuit edge case, and every time I've personally tested it, it has clearly not been the fastest. I personally use when.js because it has a bunch of features that have made my life easier, but as it happens, every time I've done a performance comparison, it's always been a tiny bit faster than Bluebird and kew. The only library that you could call 'slow' is Q, and it has not been updated in 4 years now. If you choose something for speed, test it first yourself!Apuleius
D
23

If node is using the same or later version of V8 that Chrome 32 uses then it is likely natively supported. Otherwise you will need to load 'es6-shim' (I recommend loading es5-shim first) I have no idea which version of V8 the current release of node is using.

On my node install

node --version
v0.10.24

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

What version is Chrome V32 using? (I am using Chromium v27), so would have to find documentation, but possibly 3.22.24.16

Looking in chrome://version/ seems to give the information

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

And now from a Chrome install

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
Defeatist answered 4/2, 2014 at 22:56 Comment(1)
In Windows (10) command line, the Node version check needs to be in double quotes, i.e. node -e "console.log(process.versions.v8)"Sclerosed
H
55

Although Node.js added native promise in stable version 0.12.

But due to the memory leak issue, I recommend to use bluebird to avoid the issue.


Old anwser:

Node.js added native promise support since version 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

Note: Node.js v0.11 is still in beta, be careful if use it in production.

Helmuth answered 23/6, 2014 at 17:9 Comment(6)
Does anyone know if the memory leak mentioned is still in issue in node 4/5?Korrie
Unfortunately, the answer is yes. For more information: github.com/nodejs/node/issues/4210 .Helmuth
@Korrie no, the issue linked by Chris is now closedRecurved
@JanusTroelsen well "Closing as it's not an actionable issue right now." does not sound like its fixed...Kinslow
@LJᛃ the latest comment now says "the fix landed in V8 master last year so I think it should already landed in Node now"Emrich
So this was fixed atleast by end of 2015Demodulate
A
47

I know it has been quite a long time since OP made this post, but I wanted to update those that are still managing to find this question through search.

Node.js added native support for Promises since it merged with io.js. This happened on September 8, 2015 (as per this news post on the official Node.js site) with the first stable release of Node v4.0.0.

A host of new ES6 features, such as Promises, were added with version 4. You can read more about them here.

EDIT: Of note, it appears as though Bluebird's Promise performs better than the native implementation of Promise.

Arsine answered 30/12, 2015 at 6:24 Comment(0)
H
39

It is important to point out that the accepted answer for this question is using a promise library which is not syntactically identical to the native JS promise feature as defined by the Promises/A+ spec.

If you want Node to, as closely as possible, mimic the browser then you should use the es6-promise module located at https://github.com/jakearchibald/es6-promise.

npm install es6-promise

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

Technical Differences:

One key difference in the module is in the very constructor: var foo = new Promise() is not valid in your browser, as the Promise constructor requires a function to initialize, and that function will be responsible for resolving or rejecting that promise. In the node-promises module, resolve is accessible to all users of the Promise, which breaks the encasuplation of the Promise.

Example using node-promises

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

Example using 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.

If you desire the ability to publically expose the resolve/reject capabilities you'll need to unfold the promise, example here.

Hoagy answered 19/2, 2014 at 7:18 Comment(3)
Reading through your post i decided to try es6-promise, but had some issues as I installed es6-promises, as that's what you call it right before the last code sample. Thought i'd mention it in case anyone else do the same thing.Joellejoellen
this answer is now obsoleteRecurved
as LJ mentioned, issue was closed but doesn't look like it was resolved so I don't think the answer is obsoleteDungaree
D
23

If node is using the same or later version of V8 that Chrome 32 uses then it is likely natively supported. Otherwise you will need to load 'es6-shim' (I recommend loading es5-shim first) I have no idea which version of V8 the current release of node is using.

On my node install

node --version
v0.10.24

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

What version is Chrome V32 using? (I am using Chromium v27), so would have to find documentation, but possibly 3.22.24.16

Looking in chrome://version/ seems to give the information

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

And now from a Chrome install

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
Defeatist answered 4/2, 2014 at 22:56 Comment(1)
In Windows (10) command line, the Node version check needs to be in double quotes, i.e. node -e "console.log(process.versions.v8)"Sclerosed
M
6

I tried Node v0.11.12 with the --harmony flag, and it does not have native promises.

v0.11.13 and later with the --harmony flag does have Promise.

Mariellamarielle answered 13/3, 2014 at 20:55 Comment(0)
M
3

you will need to have newest V8 version - try compiling from master branch - there you will find V8 version 3.25.30 with Promises

quick comparison with standard 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
Marella answered 11/4, 2014 at 14:13 Comment(0)
T
3

It looks like v0.12 supports promises, see node.Promise.

Truditrudie answered 15/3, 2015 at 12:30 Comment(2)
Um, that was v0. 1.12 - from 2011! And those "promises" were not even thenable from what I can read there.Lovelorn
Oh crap! Yeah, v0.1.12 versus v0.12 makes a big difference. Thanks for correcting me. So, is lack of promise support part of what is driving the IO.js uprising? Myself, for now, I just use Q.Truditrudie
T
0

Although promises are not natively in node.js (yet). The IO.js fork of node.js has them natively. See: http://davidwalsh.name/es6-io

Truditrudie answered 2/4, 2015 at 5:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.