虽然循环使用蓝鸟承诺

我正在尝试使用承诺实现一个while循环。

这里概述的方法似乎工作。 http://blog.victorquinn.com/javascript-promise-while-loop它使用这样的function

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; }; 

这似乎使用反模式和弃用的方法,如投和延期。

有没有人知道一个更好或更现代的方式来实现这一目标?

谢谢

cast转换就可以resolvedefer应该不会被使用 。

你只需通过链接和嵌套, then调用到最初的Promise.resolve(undefined)创build你的循环。

 function promiseWhile(predicate, action, value) { return Promise.resolve(value).then(predicate).then(function(condition) { if (condition) return promiseWhile(predicate, action, action()); }); } 

在这里, predicateaction可能返回承诺。 对于类似的实现也有一个正确的方法来编写循环的承诺。 接近你原来的function将是

 function promiseWhile(predicate, action) { function loop() { if (!predicate()) return; return Promise.resolve(action()).then(loop); } return Promise.resolve().then(loop); } 

我更喜欢这个实现,因为它更容易模拟中断并继续:

 var Continue = {}; // empty object serves as unique value var again = _ => Continue; var repeat = fn => Promise.try(fn, again) .then(val => val === Continue && repeat(fn) || val); 

示例1:当源或目标指示错误时停止

 repeat(again => source.read() .then(data => destination.write(data)) .then(again) 

示例2:如果硬币翻转给定90%的概率结果为0,则随机停止

 var blah = repeat(again => Promise.delay(1000) .then(_ => console.log("Hello")) .then(_ => flipCoin(0.9) && again() || "blah")); 

示例3:使用返回总和的条件循环:

 repeat(again => { if (sum < 100) return fetchValue() .then(val => sum += val) .then(again)); else return sum; })