Как правильно построить цикл, чтобы убедиться, что следующий вызов обещания и связанный logger.log (res) выполняются синхронно через итерацию? (Bluebird)
db.getUser(email).then(function(res) { logger.log(res); }); // this is a promise
Я пробовал следующий способ (метод из http://blog.victorquinn.com/javascript-promise- while-loop )
var Promise = require('bluebird');
var promiseWhile = function(condition, action) {
var resolver = Promise.defer();
var loop = function() {
if (!condition()) return resolver.resolve();
return Promise.cast(action())
.then(loop)
.catch(resolver.reject);
};
process.nextTick(loop);
return resolver.promise;
});
var count = 0;
promiseWhile(function() {
return count < 10;
}, function() {
return new Promise(function(resolve, reject) {
db.getUser(email)
.then(function(res) {
logger.log(res);
count++;
resolve();
});
});
}).then(function() {
console.log('all done');
});
Хотя вроде работает, но я не думаю, что это гарантирует порядок вызова logger.log (res);
Какие-либо предложения?
javascript
node.js
promise
bluebird
user2127480
источник
источник
loop
функцией - это способ создания синхронных циклов). Как вы думаете, почему нет гарантии?while
работает этот код?Ответы:
На самом деле это так. Этот оператор выполняется перед
resolve
вызовом.Много. Самым важным является использование вами антипаттерна create-обещание-вручную - просто делайте только
Во-вторых, эту
while
функцию можно значительно упростить:В-третьих, я бы использовал не
while
цикл (с закрывающей переменной), аfor
цикл:источник
action
принимает вvalue
качестве аргумента вpromiseFor
. ТАК не позволил бы мне сделать такое небольшое изменение. Спасибо, это очень полезно и элегантно.while
цикл действительно проверяет какое-то глобальное состояние, в то время какfor
цикл имеет свою итерационную переменную (счетчик), привязанную к самому телу цикла. Фактически я использовал более функциональный подход, который больше похож на итерацию фиксированной точки, чем на цикл. Еще раз проверьте их код,value
параметр другой..bind()
новое запутываетсяvalue
, я думаю, что я мог бы выбрать функцию от руки для удобства чтения. И извините, если я слишком толстый, но еслиpromiseFor
иpromiseWhile
не сосуществуют, то как одно может назвать другое?return …
наreturn Promise.resolve(…)
. Если вам нужны дополнительные меры защиты от исключенияcondition
илиaction
создания исключения (например,Promise.method
предоставляет его ), оберните все тело функции вreturn Promise.resolve().then(() => { … })
Promise.resolve().then(action).…
илиPromise.resolve(action()).…
, вам не нужно оборачивать возвращаемое значениеthen
Если вам действительно нужна общая
promiseWhen()
функция для этой и других целей, то обязательно сделайте это, используя упрощения Берги. Однако из-за того, как работают обещания, передача обратных вызовов таким образом обычно не нужна и заставляет вас прыгать через сложные маленькие обручи.Насколько я могу судить, вы пытаетесь:
.then()
цепочки с помощью рекурсии.Определенная таким образом, проблема на самом деле является той, которая обсуждается в разделе «Сборник Kerfuffle» в Promise Anti-patterns , который предлагает два простых решения:
Array.prototype.map()
Array.prototype.reduce()
.Параллельный подход (прямо) выявит проблему, которую вы пытаетесь избежать, - порядок ответов неопределен. Последовательный подход построит требуемую
.then()
цепочку - плоскую - без рекурсии.Звоните следующим образом:
Как видите, нет необходимости в уродливой внешней переменной var
count
или связанной с нейcondition
функции. Предел (из 10 в вопросе) полностью определяется длиной массиваarrayOfEmailAddys
.источник
Вот как я это делаю со стандартным объектом Promise.
источник
chain = chain.then(func.bind(null, "...your params here"));
либоchain = chain.then(() => func("your params here"));
Дано
необходимые
Решение
источник
async
он собирается стать зарезервированным словом в JavaScript, это может добавить ясности переименование этой функции здесь.current
он не используется.Есть новый способ решить эту проблему - использовать async / await.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function https://ponyfoo.com/articles/understanding-javascript-async-await
источник
Предлагаемая Берги функция действительно хороша:
Тем не менее, я хочу сделать небольшое дополнение, которое имеет смысл при использовании обещаний:
Таким образом, цикл while может быть встроен в цепочку обещаний и разрешается с помощью lastValue (также, если action () никогда не запускается). См. Пример:
источник
Я бы сделал что-то вроде этого:
Таким образом, dataAll представляет собой упорядоченный массив всех элементов для регистрации. И операция журнала будет выполняться, когда все обещания будут выполнены.
источник
Используйте async и await (es6):
источник
источник
Как насчет того, чтобы использовать BlueBird ?
источник
Вот еще один метод (ES6 w / std Promise). Использует критерии выхода типа lodash / подчеркивания (return === false). Обратите внимание, что вы можете легко добавить метод exitIf () в параметры для запуска в doOne ().
источник
Использование стандартного объекта обещания, при котором обещание возвращает результаты.
источник
Сначала возьмите массив обещаний (массив обещаний), а затем разрешите этот массив обещаний с помощью
Promise.all(promisearray)
.источник