我需要按顺序运行动态数量的承诺。 我理解我如何能够按顺序执行承诺,但我不会成功地通过一系列可能不同的承诺来实现它。
我发现这是一种静态How to resolve promises one after another?:
的方法
function waitFor(timeout) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(`Finished waiting ${timeout} milliseconds`);
}, timeout);
});
}
waitFor(1000).then(function(result) {
$('#result').append(result+' @ '+(new Date().getSeconds())+'<br>');
return waitFor(2000);
}).then(function(result) {
$('#result').append(result+' @ '+(new Date().getSeconds())+'<br>');
return waitFor(3000);
}).then(function(result) {
$('#result').append(result+' @ '+(new Date().getSeconds())+'<br>');
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div id="result"></div>
&#13;
我想做同样的事情但不是3个嵌套的承诺,我想要任何我想要的号码。 你能帮助我吗 ?
非常感谢!!
答案 0 :(得分:1)
创建一个seprate函数来处理迭代次数
function waitFor(timeout) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(`Finished waiting ${timeout} milliseconds`);
}, timeout);
});
}
function resultHandler(result) {
$('#result').append(result+' @ '+(new Date().getSeconds())+'<br>');
return waitFor(2000);
}
function repeat(promise,num){
if(num>0)
repeat(promise.then(resultHandler),num-1);
}
repeat(waitFor(1000),2)
答案 1 :(得分:1)
Promise有三种基本方法可以完成这项任务。
.reduce()
模式。
function waitFor(timeout) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(`Finished waiting ${timeout} milliseconds`);
}, timeout);
});
}
var timeouts = [1000, 2000, 2000, 3000, 1000],
sequence = tos => tos.reduce((p,c) => p.then(rp => waitFor(c))
.then(rc => console.log(`${rc} @ ${new Date().getSeconds()}`)), Promise.resolve());
sequence(timeouts);
function waitFor(timeout) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(`Finished waiting ${timeout} milliseconds`);
}, timeout);
});
}
var timeouts = [1000, 2000, 2000, 3000, 1000],
sequence = ([to,...tos]) => to !== void 0 && waitFor(to).then(v => (console.log(`${v} @ ${new Date().getSeconds()}`), sequence(tos)));
sequence(timeouts);
scanl
模式会一个接一个地对承诺进行排序,但一旦完成,您也可以访问临时承诺解决方案。在某些情况下,这可能很有用。如果您要懒惰地构造异步树结构(仅在需要时从节点分支),您需要访问先前的承诺解析。
为了在JS中实现scanl
功能,首先我们必须实现它。
var scanl = (xs, f, acc) => xs.map((a => e => a = f(a,e))(acc))
我们向scanl
提供xs
,这是此特定示例中的超时数组f
,它是一个回调函数,它接受acc
(累加器)和{ {1}}(当前项)并返回新的累加器。累加器值(临时承诺分辨率)映射在超时数组上,以便在需要时访问。
e
function waitFor(timeout) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(`finished waiting ${timeout} milliseconds`);
}, timeout);
});
}
var timeouts = [1000, 2000, 2000, 3000, 1000],
scanl = (xs, f, acc) => xs.map((a => e => a = f(a,e))(acc)),
proms = scanl(timeouts, // input array
(a,t,r) => a.then(v => (r = v, waitFor(t))) // callback function
.then(v => (console.log(`${r} and ${v}`),
`${r} and ${v}`)),
Promise.resolve(`Started with 0`)); // accumulator initial value
// Accessing the previous sub sequential resolutions
Promise.all(proms)
.then(vs => vs.forEach(v => console.log(v)));
答案 2 :(得分:0)
忘记我评论过(当你将Promise转换为Observable或在数组中包含promise时,执行Promise)。您可以使用“递归”功能
foolPromise(index: number, interval: number) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ id: index, data: new Date().getTime() % 100000 });
}, interval);
})
}
intervals: number[] = [1000, 50, 500];
recursive(req: any, index: number) {
req.then(res => {
console.log(res);
index++;
if (index < this.intervals.length)
this.recursive(this.foolPromise(index, this.intervals[index]), index);
})
}
ngOnInit() {
this.recursive(this.foolPromise(0, this.intervals[0]), 0)
}
答案 3 :(得分:-1)
如果您不关心序列化,可以使用Promise.all https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
wc -l
或者,您可以使用异步功能:
Promise.all([promise1, promise2, promise3]).then(function(values) {
// do something with values
}).catch(function(err) {
// error called on first failed promise
});