Понимание обещаний в Node.js

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

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

Я нашел библиотеку обещаний узлов, но не получил ее.

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

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

Ответ 1

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

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

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

Ответ 2

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

  • node -promise выглядит довольно мертвым для меня (последняя фиксация была около 1 года назад) и почти не содержит тестов.
  • Модуль фьючерсов выглядит очень раздутым для меня и плохо документирован (и я думаю, что соглашения об именах просто плохие).
  • Лучшим способом работы является q framework, который является активным и хорошо документированным.

Ответ 3

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

 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 successful execution returns and
   //error is the thing which the operation failure returns.
 });

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

Спецификация promises 'указывает, что обещание

then
Метод

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

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

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

Ответ 4

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

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

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

Ответ 5

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

Эти видео довольно информативны, и Майку удается продемонстрировать мощь 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.

Обновление Apr-2014

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

Ответ 6

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

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

Ответ 7

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

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

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

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

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

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

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

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

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

Ссылка:: promises

Ответ 8

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

Из q.js readme на github:

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