Понимание обещаний в node.js - PullRequest
145 голосов
/ 28 ноября 2010

Из того, что я понял, есть три способа вызова асинхронного кода:

  1. События: например,request.on("event", callback);
  2. Обратные вызовы: напр.fs.open(path, flags, mode, callback);
  3. Обещания

Я нашел библиотеку обещаний https://github.com/kriszyp/node-promise, но я ее не получил.

Может кто-нибудь объяснить, что такое обещаниявсе о и почему я должен использовать это?

Кроме того, почему это было удалено из Node.js?

Ответы [ 8 ]

99 голосов
/ 17 мая 2012

Поскольку этот вопрос по-прежнему имеет много точек зрения (как и у меня), я хотел бы отметить, что:

  1. нода-обещание выглядит довольно мертвой для меня (последний коммит был около 1 года назад) и почти не содержит тестов.
  2. Модуль futures выглядит для меня очень раздутым и плохо документирован (и я думаю, что соглашения об именах просто плохие)
  3. Наилучшим путем, похоже, является q framework , который является одновременно активным и хорошо документированным.
89 голосов
/ 28 ноября 2010

Promises в node.js обещал выполнить некоторую работу, а затем имел отдельные обратные вызовы, которые будут выполняться для успеха и неудачи, а также для обработки таймаутов.Еще один способ думать об обещаниях в node.js заключается в том, что они были излучателями, которые могли излучать только два события: success и error.

Крутая вещь в обещаниях заключается в том, что вы можете объединять их в цепочки зависимостей (выполняйте только Promise Cкогда Promise A и Promise B завершены).

Удалив их из ядра node.js, он создал возможность создания модулей с различными реализациями обещаний, которые могут располагаться поверхядро.Некоторые из них узел-обещание и фьючерсы .

19 голосов
/ 23 мая 2014

Обещание - это «вещь», которая представляет, так сказать, «возможные» результаты операции. Здесь следует отметить, что он абстрагирует детали , когда что-то происходит, и позволяет вам сосредоточиться на том, что должно произойти после , если что-то происходит. Это приведет к чистому, поддерживаемому коду, где вместо обратного вызова внутри обратного вызова внутри обратного вызова ваш код будет выглядеть примерно так:

 var request = new Promise(function(resolve, reject) {
   //do an ajax call here. or a database request or whatever.
   //depending on its results, either call resolve(value) or reject(error)
   //where value is the thing which the operation's successful execution returns and
   //error is the thing which the operation's failure returns.
 });

 request.then(function successHandler(result) {
   //do something with the result
 }, function failureHandler(error) {
  //handle
 });

Спецификация обещаний гласит, что обещание

then

метод должен возвращать новое обещание, которое выполняется, когда заданный обратный вызов successHandler или failHandler завершен. Это означает, что вы можете связывать воедино обещания, когда у вас есть набор асинхронных задач, которые необходимо выполнить, и вы можете быть уверены, что последовательность операций гарантирована так же, как если бы вы использовали обратные вызовы. Таким образом, вместо передачи обратного вызова внутри обратного вызова внутри обратного вызова, код с связанными обещаниями выглядит так:

var doStuff = firstAsyncFunction(url) {
                return new Promise(function(resolve, reject) {
                       $.ajax({
                        url: url,
                        success: function(data) {
                            resolve(data);
                        },
                        error: function(err) {
                             reject(err); 
                        } 
                  });
               };
doStuff
  .then(secondAsyncFunction) //returns a promise
  .then(thirdAsyncFunction); //returns a promise

Чтобы узнать больше об обещаниях и о том, почему они очень крутые, загляните в блог Доменика: http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/

12 голосов
/ 25 мая 2015

Этот новый учебник об обещаниях от автора PouchDB , вероятно, лучший из всех, что я когда-либо видел.Он мудро охватывает классические ошибки новичков, показывая вам правильные шаблоны использования и даже несколько анти-шаблонов, которые все еще широко используются - даже в других уроках !!

Наслаждайтесь!

PS Я не ответил на некоторые другие части этого вопроса, так как они были хорошо освещены другими.

7 голосов
/ 13 декабря 2012

Mike Taulty имеет серию видеороликов , каждый из которых менее десяти минут, описывающих работу библиотеки WinJS Promise.

Эти видеоролики довольно информативны, и Майку удается продемонстрировать всю мощь API Promise с помощью нескольких удачно выбранных примеров кода.

var twitterUrl = "http://search.twitter.com/search.json?q=windows";
var promise = WinJS.xhr({ url: twitterUrl });

 promise = promise.then(
     function (xhr) {
     },
     function (xhr) {
         // handle error
     });

Особенно хороша трактовка исключений.

Несмотря на ссылки на WinJs, это серия видеофильмов общего интереса, потому что API Promise в целом схожи во многих своих реализациях.

RSVP - это облегченная реализация Promise, которая проходит тестовый набор Promise / A +. Мне очень нравится API, потому что он похож по стилю на интерфейс WinJS.

Обновление апрель-2014

Кстати, библиотека WinJS теперь с открытым исходным кодом .

5 голосов
/ 14 марта 2014

Еще одним преимуществом обещаний является то, что обработка ошибок и создание и перехват исключений намного лучше, чем попытка обработать это с помощью обратных вызовов.

Библиотека bluebird реализует обещания и дает вам отличные длинные трассировки стека, очень быстра и предупреждает о необработанных ошибках. Он также работает быстрее и использует меньше памяти, чем другие библиотеки обещаний, согласно http://bluebirdjs.com/docs/benchmarks.html

4 голосов
/ 18 мая 2017

Что такое Обещание?

Обещание - это просто объект, представляющий результат асинхронной операции. Обещание может быть в любом из следующих 3 состояний:

в ожидании :: Это начальное состояние, означающее, что обещание не выполнено и не отклонено.

выполнено :: Это означает, что обещание выполнено, означает, что значение, представленное обещанием, готово к использованию.

отклонено :: Это означает, что операции завершились неудачно и, следовательно, не могут выполнить обещание. Помимо штатов, есть три важных объекта, связанных с обещаниями, которые нам действительно необходимо понять

  1. executor function :: executor function определяет асинхронную операцию, которая должна быть выполнена и чей результат представлен обещанием. Он начинает выполнение сразу после инициализации объекта обещания.

  2. resol :: resolle - это параметры, передаваемые в функцию executor, и в случае успешного выполнения executor это разрешение вызывается с передачей результата.

  3. reject :: reject - это еще один параметр, передаваемый в функцию executor, и он используется при сбое функции executor. Причина отказа может быть передана на отклонение.

Поэтому, когда мы создаем объект обещания, мы должны предоставлять Executor, Resolve и Reject.

Ссылка :: Обещания

0 голосов
/ 13 июня 2014

Я также недавно изучал обещания в node.js.До настоящего времени when.js , кажется, является подходящим вариантом из-за его скорости и использования ресурсов, но документация по q.js дала мне намного лучшее понимание.Так что используйте when.js, а не документы q.js, чтобы понять предмет.

Из q.js readme на github:

Если функция не можетвернуть значение или выдать исключение без блокировки, вместо этого он может вернуть обещание.Обещание - это объект, представляющий возвращаемое значение или выброшенное исключение, которое функция может в конечном итоге предоставить.Обещание также можно использовать в качестве прокси для удаленного объекта, чтобы преодолеть задержку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...