Власна підтримка обіцянок у Node.js


76

Чи існує вбудована підтримка обіцянок у поточних версіях Node.js?

Node.js використовує движок V8. Цей механізм JavaScript також використовується Chrome, і Chrome 32 має вбудовану підтримку для обіцянок. Але я, здається, не можу отримати обіцянки працювати (спочатку) в 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/


1
Власна підтримка в Node не є надто корисною, поки всі модулі не почнуть її використовувати. Пообіцяйте всі речі.
Руді


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!
Тревор,

6
Будь ласка, будь ласка, майте на увазі, що претензії Bluebird на те, що вони найшвидші, наразі давні, її претензії на швидкість були по суті лише випадком короткого замикання, і кожного разу, коли я особисто тестував це, це явно не було найшвидшим. Я особисто використовую When.js, оскільки він має безліч функцій, які полегшили мені життя, але, як це трапляється, кожного разу, коли я роблю порівняння продуктивності, це завжди було трохи крихітніше, ніж Bluebird і Kew. Єдиною бібліотекою, яку ви можете назвати "повільною", є Q, і вона не оновлюється вже 4 роки. Якщо ви вибираєте щось для швидкості, спробуйте це спочатку самі!
Ендрю

Відповіді:


23

Якщо вузол використовує ту саму або пізнішу версію V8, яку використовує Chrome 32, це, швидше за все, підтримується рідно. В іншому випадку вам потрібно буде завантажити 'es6-shim' (я рекомендую спочатку завантажити es5-shim ). Я не уявляю, яку версію V8 використовує поточний випуск вузла.

На моєму вузлі встановлення

node --version
v0.10.24

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

Яку версію використовує Chrome V32? (Я використовую Chromium v27), тому довелося б знайти документацію, але можливо 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 додав підтримку власних обіцянок з моменту версії 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.js v0.11все ще знаходиться в бета-версії, будьте обережні, якщо використовуєте його у виробництві.


2
Хтось знає, чи згаданий витік пам'яті все ще є проблемою у вузлі 4/5?
1nfiniti

1
На жаль, відповідь так. Для отримання додаткової інформації: github.com/nodejs/node/issues/4210 .
Кріс

@ 1nfiniti ні, питання, пов’язане Крісом, тепер закрите
Янус Троелсен,

1
@JanusTroelsen ну "Закриття, оскільки зараз це не є проблемою, яка може бути вирішена" . не схоже на виправлене ...
ЖЖ,

1
@LJ ᛃ в останньому коментарі зараз сказано "виправлення потрапило у V8 master минулого року, тому я думаю, що воно вже повинно було потрапити в Node зараз"
Aur Saraf,

43

Я знаю, що минуло досить багато часу з моменту, коли ОП зробила цю публікацію, але я хотів оновити тих, кому все ще вдається знайти це питання за допомогою пошуку.

Node.js додав рідну підтримку для Promises, оскільки він об’єднався з io.js. Це сталося 8 вересня 2015 р. (Відповідно до цієї публікації новин на офіційному сайті Node.js) з першим стабільним випуском Node v4.0.0.

Безліч нових функцій ES6, таких як Promises, було додано до версії 4. Більше про них можна прочитати тут .

РЕДАГУВАТИ: Зауважимо, здається, ніби Bluebird's Promise працює краще, ніж рідна реалізація Promise .


39

Важливо зазначити, що прийнятою відповіддю на це питання є використання бібліотеки обіцянок, яка синтаксично не ідентична власній функції обіцянки JS, як визначено специфікацією Promises / A + .

Якщо ви хочете, щоб 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, що порушує обвинувачення 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-promis, але мав деякі проблеми, оскільки встановив es6-promis s , як це ви називаєте безпосередньо перед останнім зразком коду. Думав, я згадаю про це, якщо хтось інший зробить те саме.
hansn

ця відповідь вже застаріла
Янус Трольсен

як згадував ЖЖ, питання було закрито, але схоже, що воно вирішене, тому я не думаю, що відповідь застаріла
ABCD.ca

6

Я спробував Node v0.11.12 з прапором --harmony, і він не має власних обіцянок.

v0.11.13 і пізніше з прапором --harmony має Promise.


3

вам потрібно буде мати найновішу версію 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

3

Схоже, v0.12 підтримує обіцянки, див. Node.Promise .


2
Гм, це було v0. 1 .12 - з 2011 року! І ці "обіцянки" навіть не можна було уникнути з того, що я можу там прочитати.
Бергі,

Ось лайно! Так, v0.1.12 проти v0.12 має велике значення. Дякую за виправлення. Отже, чи відсутність підтримки обіцянок є частиною того, що є рушієм повстання IO.js ? Я, в даний час, я просто використовую Q .
Лонні Бест,

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.