Понимание обещаний в Node.js
Из того, что я понял, есть три способа вызова асинхронного кода:
- События, например
request.on("event", callback);
- Обратные вызовы, например
fs.open(path, flags, mode, callback);
- Обещания
Я нашел библиотеку обещаний узлов, но не получил ее.
Может ли кто-нибудь объяснить, что это за обещания и почему я должен их использовать?
Кроме того, почему он был удален из 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:
Если функция не может вернуть значение или исключить исключение блокируя, он может вернуть обещание вместо этого. Обещание - это объект, который представляет возвращаемое значение или исключенное исключение, что функция может в конечном итоге обеспечить. Обещание также может быть использовано в качестве прокси-сервера для удаленный объект для преодоления латентности.