我有一段使用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
进行顺序执行。我尝试使用相同但没有太多运气。
任何建议都将不胜感激。
答案 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());