我怎么能一个接一个地发起承诺?
waitFor(t)
是一个函数,它返回一个在t
时间后解析的promise。我希望能够做到的是:
waitFor(1000) Then when finished, console.log('Finished wait of 1000 millis') then
waitFor(2000) Then when finished, console.log('Finished wait of 2000 millis') then
waitFor(3000) Then when finished, console.log('Finished wait of 3000 millis')
以下是我的尝试:
waitFor(1000).then(function(resolve, reject) {
console.log(resolve);
}).then(waitFor(2000).then(function(resolve, reject) {
console.log(resolve);
})).then(waitFor(3000).then(function(resolve, reject) {
console.log(resolve);
}));
不幸的是,这个console.logs每隔1秒就记录一次,这意味着所有一次调用的承诺。
我设法用这样的回调解决了这个问题,但这让一切变得非常难看:
waitFor(1000).then(function(resolve, reject) {
console.log(resolve+' @ '+(new Date().getSeconds()));
waitFor(2000).then(function(resolve, reject) {
console.log(resolve+' @ '+(new Date().getSeconds()));
waitFor(3000).then(function(resolve, reject) {
console.log(resolve+' @ '+(new Date().getSeconds()));
});
});
});
那么我应该怎么做才能使它有效,但却没有使用丑陋的回调地狱呢?
不受欢迎的结果:http://jsfiddle.net/nxjd563r/1/
答案 0 :(得分:3)
我找到了你的解决方案。
您需要让每个then
返回一个新的承诺,以便下一个then
可以在前一个{1}}解决之后作出反应。
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>');
});
jsfiddle http://jsfiddle.net/4xxps2cg/2/
答案 1 :(得分:2)
您可以将promises放入数组并使用reduce
将它们链接起来,从一个额外的已解决的承诺开始。
function waitPromise(time) {
//console.log(time);
return new Promise( (resolve,reject) => {
setTimeout( () => {resolve('resolved');}, time);
});
}
function log(data) {
return new Promise( (resolve,reject) => {
console.log( data +' @ '+(new Date().getSeconds()));
resolve();
});
}
var ps = [];
for (var i=0;i<3;i++) {
let time = (i+1) * 1000;
ps.push( () => waitPromise(time) );
ps.push( log );
}
console.log( 'started' +' @ '+(new Date().getSeconds()));
var p = Promise.resolve();
ps.reduce( (p,c) => {return p.then(c)}, p);
答案 2 :(得分:1)
waitFor()
似乎立即在.then()
被调用;尝试从waitFor()
匿名函数中返回.then()
。
可以创建持续时间值数组,使用Array.prototype.shift()
连续调用waitFor
每个持续时间值,或者将参数timeout
传递给waitFor
;如果在每个.then()
调用相同的流程,请将.then()
中的流程包含在Promise
中的waitFor
;在waitFor
链接到初始.then()
调用
waitFor()
调用
var t = [1000, 2000, 3000];
function waitFor(timeout) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("`Finished waiting ${timeout} milliseconds`");
}, timeout && t.shift() || t.shift());
}).then(function (data) {
$('#result').append(data + ' @ ' + new Date().getSeconds() + '<br/>');
})
}
waitFor().then(waitFor).then(waitFor)
//.then(function() {return waitFor(5000)})
答案 3 :(得分:0)
调用和等待的格式有点偏,你的then
应该是一个返回一个promise的函数,因为现在你传递一个函数调用而不是一个函数,它立即运行该请求而不是由于承诺等待调用该函数。
这应该这样做:
function waitFor(timeout) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(`Finished waiting ${timeout} milliseconds`);
}, timeout);
});
}
waitFor(1000).then(function(resolve, reject) {
$('#result').append(resolve+' @ '+new Date().getSeconds()+'<br/>');
}).then(function(){
return waitFor(2000)
}).then(function(resolve, reject) {
$('#result').append(resolve+' @ '+new Date().getSeconds()+'<br/>');
}).then(function() {
return waitFor(2000)
}).then(function(resolve, reject) {
$('#result').append(resolve+' @ '+new Date().getSeconds()+'<br/>');
})