Я хочу работать с обещаниями, но у меня есть API обратного вызова в таком формате:
1. Загрузка DOM или другое одноразовое событие:
window.onload; // set to callback
...
window.onload = function() {
};
2. Простой обратный вызов:
function request(onChangeHandler) {
...
}
request(function() {
// change happened
...
});
3. Обратный вызов стиля узла («nodeback»):
function getStuff(dat, callback) {
...
}
getStuff("dataParam", function(err, data) {
...
})
4. Целая библиотека с обратными вызовами в стиле узла:
API;
API.one(function(err, data) {
API.two(function(err, data2) {
API.three(function(err, data3) {
...
});
});
});
new Promise
добавление какие-либо существенные накладные расходы? Я хочу обернуть все мои синхронные функции Noje.js в Promise, чтобы удалить весь синхронный код из моего Node-приложения, но так ли это лучше? Другими словами, функция, которая принимает статический аргумент (например, строку) и возвращает вычисленный результат, я должен обернуть это в обещание? ... Я где-то читал, что у вас не должно быть никакого синхронного кода в Nodejs.Ответы:
Обещания имеют статус, они начинаются как ожидающие и могут рассчитывать на:
Функции возврата обещаний никогда не должны выдаваться, вместо этого они должны возвращать отклонения. Функция возврата из обещания заставит вас использовать и a,
} catch {
и a.catch
. Люди, использующие обещанные API-интерфейсы, не ожидают обещаний. Если вы не уверены, как работают асинхронные API в JS - сначала посмотрите этот ответ .1. Загрузка DOM или другое одноразовое событие:
Таким образом, создание обещаний обычно означает указание того, когда они рассчитываются, то есть когда они переходят к выполненной или отклоненной фазе, чтобы указать, что данные доступны (и могут быть доступны с помощью
.then
).С современными реализациями обещаний, которые поддерживают
Promise
конструктор как родные обещания ES6:Затем вы будете использовать полученное обещание так:
С библиотеками, которые поддерживают отложенный (давайте используем здесь $ q для этого примера, но позже мы также будем использовать jQuery):
Или с помощью jQuery-подобного API, перехватывая событие, происходящее один раз:
2. Простой обратный вызов:
Эти API довольно распространены, так как ... обратные вызовы распространены в JS. Давайте посмотрим на общий случай наличия
onSuccess
иonFail
:С современными реализациями обещаний, которые поддерживают
Promise
конструктор как родные обещания ES6:С библиотеками, которые поддерживают отложенный (давайте используем jQuery для этого примера здесь, но мы также использовали $ q выше):
jQuery также предлагает
$.Deferred(fn)
форму, которая позволяет нам написать выражение, которое очень близко имитируетnew Promise(fn)
форму, следующим образом:Примечание: здесь мы используем тот факт, что jQuery deferred
resolve
иreject
методы являются «отделяемыми»; то есть. они привязаны к экземпляру jQuery.Deferred (). Не все библиотеки предлагают эту функцию.3. Обратный вызов стиля узла («nodeback»):
Обратные вызовы стиля узла (nodebacks) имеют определенный формат, где обратные вызовы всегда являются последним аргументом, а его первый параметр является ошибкой. Давайте сначала пообещаем одно вручную:
Для того, чтобы:
С deferreds вы можете сделать следующее (давайте используем Q для этого примера, хотя Q теперь поддерживает новый синтаксис, который вы должны предпочесть ):
В общем, вам не следует слишком много обещать вручную, в большинстве библиотек обещаний, которые были разработаны с учетом Node, а также в собственных обещаниях в Node 8+ есть встроенный метод для обещания обратных узлов. Например
4. Целая библиотека с обратными вызовами в стиле узла:
Здесь нет золотого правила, вы обещаете их один за другим. Тем не менее, некоторые реализации обещаний позволяют вам делать это массово, например, в Bluebird, преобразование API обратной ноды в API обещаний так же просто, как:
Или с нативными обещаниями в Node :
Ноты:
.then
обработчике, вам не нужно ничего обещать. Возврат обещания от.then
обработчика разрешит или отклонит значение этого обещания. Бросок из.then
обработчика также является хорошей практикой и отвергнет обещание - это знаменитое обещание безопасности броска.onload
случае вы должны использовать,addEventListener
а неonX
.источник
resolve()
иreject()
написано , чтобы быть многоразовыми, я рискую , что мои предложили изменить это значение , поскольку он предлагает пример JQuery формы$.Deferred(fn)
, которая в противном случае отсутствует. Если включен только один пример jQuery, то я предлагаю, чтобы он имел такую форму, а неvar d = $.Deferred();
и т. Д., Поскольку людям следует поощрять использование часто пренебрегаемой$.Deferred(fn)
формы, плюс в ответе, подобном этому, он ставит jQuery в один ряд с libs, которые используют шаблон Revealing Constructor .$.Deferred(fn)
, если вы отредактируете это вместо существующего примера в течение следующих 15 минут, я уверен, что могу попытаться утвердить его вовремя :)util.promisify
, что Node.js собирается добавить в свое ядро начиная с RC 8.0.0. Его работа не сильно отличается от BluebirdPromise.promisify
, но имеет то преимущество, что не требует дополнительных зависимостей, в случае, если вы просто хотите родной Promise. Я написал сообщение в блоге об util.promisify для тех, кто хочет узнать больше на эту тему.Сегодня я могу использовать
Promise
вNode.js
качестве простого метода Javascript.Простой и простой пример
Promise
(с KISS way):Простой Javascript Async API-код:
Promise
Код Javascript Async API:(Я рекомендую посетить этот прекрасный источник )
Также
Promise
может быть использовано с тусовкойasync\await
в ,ES7
чтобы сделать ожидание потока программы дляfullfiled
результата , как в следующем:Другое использование с тем же кодом с использованием
.then()
методаPromise
также может использоваться на любой платформе, основанной на Node.js, напримерreact-native
.Бонус : гибридный метод
(предполагается, что метод обратного вызова имеет два параметра как ошибку и результат)
Вышеупомянутый метод может ответить на результат для старого способа обратного вызова и обещаний использования.
Надеюсь это поможет.
источник
Перед преобразованием функции в качестве обещания в Node.JS
После преобразования
Incase вам нужно обработать несколько запросов
источник
Я не думаю, что
window.onload
предложение @Benjamin будет работать постоянно, так как оно не определяет, вызывается ли оно после загрузки. Я был укушен этим много раз. Вот версия, которая всегда должна работать:источник
setTimeout(resolve, 0)
(илиsetImmediate
, если возможно) ветку , чтобы она вызывалась асинхронно?resolve
в порядке.then
Обработчики Promise гарантируются асинхронным вызовом платформы независимо от того,resolve
вызывается ли синхронно.Node.js 8.0.0 включает новый
util.promisify()
API, который позволяет обернуть стандартные API стиля обратного вызова Node.js в функцию, которая возвращает Promise. Пример использованияutil.promisify()
показан ниже.См. Улучшенная поддержка для обещаний
источник
В выпуске кандидата на Node.js 8.0.0 появилась новая утилита
util.promisify
(я писал об util.promisify ), которая заключает в себе способность обещать любую функцию.Он не сильно отличается от подходов, предложенных в других ответах, но имеет то преимущество, что является основным методом и не требует дополнительных зависимостей.
Тогда у вас есть
readFile
метод, который возвращает нативныйPromise
.источник
util.promisify
дважды (еще в 2014 году, когда этот вопрос был написан, и несколько месяцев назад - который я настаивал на том, чтобы стать основным членом Node, и это текущая версия, которую мы имеем в Node). Поскольку он еще не является общедоступным - я еще не добавил его к этому ответу. Мы были бы очень признательны за отзывы об использовании и знакомство с некоторыми подводными камнями, чтобы иметь лучшие документы для релиза :)util.promisify
в своем блоге :)util.promisify.custom
символа можно переопределить результат util.promisify? Честно говоря, это было преднамеренное промах, потому что я пока не могу найти полезного варианта использования. Возможно, вы можете дать мне некоторые входные данные?fs.exists
или API-интерфейсы, которые не следуют соглашению Node - синяя птицаPromise.promisify
может ошибиться, но сделаетutil.promisify
это правильно.Вы можете использовать собственные обещания JavaScript с Node JS.
Ссылка на код моего облака 9: https://ide.c9.io/adx2803/native-promises-in-node
источник
С простым старым ванильным javaScript вот решение для обещания обратного вызова API.
источник
Библиотека Q от kriskowal включает функции обратного вызова к обещанию. Такой метод:
можно конвертировать с помощью Q.ninvoke
источник
Q.denodeify
. Нужно ли выделять библиотечных помощников?Если у вас есть несколько функций, которые принимают обратный вызов, и вы хотите, чтобы они вместо этого возвращали обещание, вы можете использовать эту функцию для выполнения преобразования.
источник
Под узлом v7.6 +, который имеет встроенные обещания и асинхронность:
Как пользоваться:
источник
В Node.js 8 вы можете обещать методы объекта на лету, используя этот модуль npm:
https://www.npmjs.com/package/doasync
Он использует util.promisify и Proxies, чтобы ваши объекты оставались неизменными. Мемоизация также выполняется с использованием WeakMaps). Вот некоторые примеры:
С объектами:
С функциями:
Вы даже можете использовать native
call
иapply
для привязки некоторого контекста:источник
Вы можете использовать встроенный Promise в ES6, например, для работы с setTimeout:
В этом примере Обещание не имеет причин для отказа, поэтому
reject()
никогда не вызывается.источник
Функция стиля обратного вызова всегда такая (почти все функции в node.js - это стиль):
Этот стиль имеет ту же особенность:
функция обратного вызова передается последним аргументом.
функция обратного вызова всегда принимает объект ошибки в качестве первого аргумента.
Таким образом, вы можете написать функцию для преобразования функции с этим стилем следующим образом:
Для краткости в приведенном выше примере используется ramda.js. Ramda.js - отличная библиотека для функционального программирования. В приведенном выше коде мы использовали его apply (как javascript
function.prototype.apply
) и append (как javascriptfunction.prototype.push
). Итак, теперь мы можем преобразовать функцию стиля обратного вызова в функцию обещания стиля:Функции toPromise и checkErr принадлежат библиотеке berserk , это функциональная вилка библиотеки программирования от ramda.js ( созданная мной).
Надеюсь, что этот ответ полезен для вас.
источник
Вы можете сделать что-то вроде этого
Тогда используйте это
источник
es6-promisify
преобразует функции на основе обратного вызова в функции на основе Promise.Ссылка: https://www.npmjs.com/package/es6-promisify
источник
Моя многообещающая версия
callback
функции - этоP
функция:P
Функция требует обратного вызова подпись должна бытьcallback(error,result)
.источник
util.promisify(fn)
(err, value) => ...
или вы должны определить собственную (см. Пользовательские обещанные функции). Спасибо, хороший кальян.var P = function (fn, ...args) { return new Promise((resolve, reject) => fn.call(this, ...args, (error, result) => error ? reject(error) : resolve(result))); };
сделал бы то же самое, что и вы, и это намного проще.Ниже приведена реализация того, как функция (API обратного вызова) может быть преобразована в обещание.
источник
Это на 5 лет позже, но я хотел опубликовать здесь мою версию с промыслами, которая берет функции из API обратных вызовов и превращает их в обещания
Взгляните на эту очень простую версию здесь: https://gist.github.com/jdtorregrosas/aeee96dd07558a5d18db1ff02f31e21a
источник