While loop using bluebird promises

旧巷老猫 提交于 2019-12-17 05:05:42

问题


I am trying to implement a while loop using promises.

The method outlined here seems to work. http://blog.victorquinn.com/javascript-promise-while-loop it uses a function like this

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

This seems to use anti-patterns and deprecated methods like cast and defer.

Does anyone know a better or more modern way to accomplish this?

Thanks


回答1:


cast can be translated to resolve. defer should indeed not be used.

You'd create your loop only by chaining and nesting then invocations onto an initial Promise.resolve(undefined).

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

Here, both predicate and action may return promises. For similar implementations also have a look at Correct way to write loops for promise. Closer to your original function would be

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



回答2:


I prefer this implementation as its easier to simulate break and continue with it:

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

Example 1: stops when either the source or the destination indicate an error

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

Example 2: stop randomly if the coin flip given 90% probability results with a 0

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

Example 3: Loop with condition that returns the sum:

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


来源:https://stackoverflow.com/questions/29375100/while-loop-using-bluebird-promises

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!