承诺q.allSettled为q.reduce

时间:2016-06-20 20:16:50

标签: node.js promise

我有一段使用q promise库的代码:

var q = require('q')
var promises = [ promise1, promise2, promise3]
q.allSettled(promises)
    .then( function(results) {
        for( var i=0; i<results.length; ++i ) { 
           if( results[i].state = 'fulfilled' ) { //do Something on success}
           else{ //do something on failure}
        }
})

这将并行执行所有承诺。如何将其转换为顺序执行? 我确实环顾了Q Documentation,建议是使用[].reduce进行顺序执行。我尝试使用相同但没有太多运气。

任何建议都将不胜感激。

2 个答案:

答案 0 :(得分:0)

没有&#34;执行承诺&#34;。 Promise是异步操作的结果的代理。执行承诺类似于执行数字5。

可以同步执行的是返回承诺的函数。这是reduce可以做的事情。

您可以使用.reflect原语而不是allSettled

var functions = [promiseReturningFn1, promiseReturningFn2, promiseReturningFn3];
functions.reduce((soFar, current) => {
  return soFar.then(() => // wait for previous actions
    return current().reflect();
  });
}, Q());

建立.reflect(),因为Q还没有:

Q.prototype.reflect = function() {
    var p = this;
    return p.then(v => ({ state: "fulfilled", value: v }),
            .catch(r => ({ state: "rejected", reason: r }));
}

这将按顺序运行所有操作,但会在出错时继续运行它们。

答案 1 :(得分:0)

让我把我的例子放在这里。可能会有帮助。

我们有一个数字 10,我们希望始终减去数字 2、1、3。

所以结果应该是 8、7、4。

import Q from 'q';

let sum = 10;
const nums = [2, 1, 3];

const generatePromise = (num) => {
    return new Promise((resolve) => {
        setTimeout(() => {
            sum -= num
            console.log('sum', sum);
            resolve(sum);
        });
    })
}

// let's create an array of our promises
const promises = [];
nums.forEach(num => promises.push(generatePromise(num)));

// let's use Q.all to get the result
await Q.all(promises).then(data => console.log(data)); // [ 8, 7, 4 ]

它按预期工作!

但是如果执行时间会不同呢?

const generatePromise = (num) => {
    return new Promise((resolve) => {
        setTimeout(() => {
            sum -= num
            resolve(sum);
        }, 1000 * num); // <----- let's wait 2 sec for the first promise, 1 sec for the second one, and 3 sec for the last one
    })
}

现在我们得到了一个错误的结果 - [ 7, 9, 4 ]

如何解决?这是一个解决方案:

let sum = 10;
const nums = [2, 1, 3];

const generatePromise = (num) => {
    return new Promise((resolve) => {
        setTimeout(() => {
            sum -= num
            console.log('sum', sum);
            resolve(sum);
        }, 1000 * num);
    })
}

nums.reduce(async (previousPromise, num) => {
    await previousPromise;
    return generatePromise(num);
}, Promise.resolve());