Дополнительно
Цикл while с обещаниями
Что бы быть идиоматические способ сделать что-то вроде цикла while с обещаниями. Так:
что-то делать если состояние все же стоит сделать это снова повторить потом сделать что-то еще.
dosomething.then(possilblydomoresomethings).then(finish)
Я'ве сделали это таким образом, я было интересно, если есть лучше/более idomatic стороны?
var q = require('q');
var index = 1;
var useless = function(){
var currentIndex = index;
console.log(currentIndex)
var deferred = q.defer();
setTimeout(function(){
if(currentIndex > 10)
deferred.resolve(false);
else deferred.resolve(true);
},500);
return deferred.promise;
}
var control = function(cont){
var deferred = q.defer();
if(cont){
index = index + 1;
useless().then(control).then(function(){
deferred.resolve();
});
}
else deferred.resolve();
return deferred.promise;
}
var chain = useless().then(control).then(function(){console.log('done')});
Выход: 1 2 3 4 5 6 7 8 9 10 11 сделано
69
13
Здесь's в функцию для повторного использования, как мне кажется, довольно ясно.
Это самый простой способ я'вэ нашел для выражения основной схеме: вы определяете функцию, которая вызывает обещание, проверяет ее результат, а затем вызывает саму себя снова или прекращается.
в
[Увидеть его в действии на JSBin](https://jsbin.com/wirumixojo/edit?js консоль)
Если вы используете обещание, которое разрешает или отвергает, вы можете определить
тогда
ипоймать
вместо использования если-пункте.Если вы имели многочисленные обещания, вы бы просто изменить цикл, чтобы сместить или поп следующему каждый раз.
Редактировать: здесь'ы на версию, которая использует асинхронный/ждут, потому что это'ы 2018:
Увидеть его в действии на сайт CodePen
Как вы можете видеть, он использует обычный цикл while и рекурсии.
Я'd использовать объект, чтобы обернуть ценности. Таким образом, вы можете иметь собственность на "готово", чтобы петли знаю, что вы'повторно сделано.
Это для Синей птицы не вопрос, но поскольку вы ничего'т упомянуть вопрос конкретно.. в Синей птице по API док автор упоминает возвращение обещание-производящая функция будет более устойчивым, чем через deferreds.
Поскольку я могу'т комментировать Стюарт К'ы ответ Я'будете добавлять немного здесь. На основе Стюарт К'ы ответ можно свести к удивительно простой концепцией: использовать неисполненное обещание. То, что он является по сути:
Стюарт's в ответ на более общие решения, но основы являются удивительными (как только вы поймете, как это работает).
Эта картина теперь более легко вызывается с помощью Q-расход. Например, для вышеуказанной проблемы:
Вот дополнения к
обещание
прототип, чтобы имитировать поведениедля
петли. Он поддерживает обещаний или непосредственных значений для инициализация, условие, тело цикла, и увеличить разделы. Она также имеет полную поддержку исключений, и это не имеет утечек памяти. Ниже приводится один пример о том, как использовать его.Я сейчас использую этот:
Это принимает массив
Арр
ифункция
и возвращаетобещание
. Предоставленная функция вызывается один раз для каждого элемента в массиве и передается текущий элемент и он'индекс S в массиве. Это может быть синхронный или асинхронный, и в этом случае он должен возвращать обещание.Вы можете использовать его как это:
Каждый элемент в массиве будут обрабатываться по очереди. После того, как все обрабатываются, код дали
.тогда () будет работать, или, если произошла какая-то ошибка, код дали
.поймать(). Внутри "работу" функции, вы можете "бросок"
ошибки` (в случае синхронной функции) или "отклонить" на "обещания" (в случае асинхронных функций), чтобы прервать цикл.в
в
Много ответов здесь и то, что вы пытаетесь достичь, это не очень практично. но это должно работать. Это было реализовано в функцию AWS лямбда, с Node.js 10 он будет идти до тайм-аута функция. Он также может потреблять приличное количество памяти.
Проверено на лямда и работает нормально на протяжении 5 минут. Но как говорится, это не хорошая вещь, чтобы сделать.
Используя ЕС6 обещаю, я придумал это. Это цепи обещаний и возвращает обещание. Это's не технически цикла while, но как перебрать обещает синхронно.
в
в
[Здесь'с моей скрипкой.][1]
Я думал, я мог бы также бросить свою шляпу в кольцо, используя на ES6 обещания...
В
исполнитель
аргумент то же как то прошел наобещание
конструктор, но будет называться до тех пор, пока это вызывает успех обратного вызова. Функцияbefore_retry
позволяет пользовательские обработки ошибок на неудачные попытки. Если она возвращает значение ИСТИНА, он будет рассматриваться как одна из форм успеха и "петли" и закончится, что истина как результат. Если нет before_retry функциязарегистрирована, или она возвращает значение falsey, то цикл будет выполняться повторно. Третий вариант заключается в том, что функция
before_retry` бросает себя ошибку. Если это произойдет, то в "петли" и закончится, передавая эту ошибку как ошибку.Вот пример:
Выходной параметр 0:
Выход для варианта 1:
Выход для варианта 2:
Я написал модуль, который поможет вам сделать скованные петли асинхронных задач с обещаниями, он основан на выше ответ juandopazo
https://github.com/CascadeEnergy/promise-seedloop