Javascript 如何解决一个又一个承诺?

Javascript 如何解决一个又一个承诺?,javascript,node.js,callback,promise,Javascript,Node.js,Callback,Promise,我怎么能一个接一个地信守诺言呢 waitFor(t),是一个函数,它返回一个在t时间之后解析的承诺。我希望能够做到的是: 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

我怎么能一个接一个地信守诺言呢

waitFor(t)
,是一个函数,它返回一个在
t
时间之后解析的承诺。我希望能够做到的是:

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.log每隔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()));
        });
    });
});
那么,我应该如何通过承诺做到这一点,使其工作,但不是使用丑陋的回调地狱

意外结果:

期望的结果:

waitFor()
似乎在
处立即被调用;尝试从
内返回
waitFor()
。然后()返回匿名函数

也可以创建持续时间值数组,使用
array.prototype.shift()
连续调用
waitFor
,或将参数
timeout
传递给
waitFor
;如果在每个
.then()
调用相同的进程,则在
中包含进程。然后()
链接到
中的
Promise
;在
处调用相同的函数
waitFor
。然后()
链接到初始
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)})
var t=[100020003000];
函数waitFor(超时){
返回新承诺(功能(解决、拒绝){
setTimeout(函数(){
解析(`Finished waiting${timeout}毫秒`);
},超时和&t.shift()| | t.shift());
}).then(功能(数据){
$(“#结果”).append(数据+'@'+新日期().getSeconds()++'
); }) } waitFor().then(waitFor).then(waitFor) //.then(函数(){return waitFor(5000)})
我找到了你的解决方案

您需要让每个
then
返回一个新的承诺,以便下一个
then
可以在前一个承诺得到解决后做出反应

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>');
});
waitFor(1000)。然后(函数(结果){
$(“#结果”).append(结果+'@'+(新日期().getSeconds())+'
); 等待返回(2000年); }).然后(函数(结果){ $(“#结果”).append(结果+'@'+(新日期().getSeconds())+'
); 返回等待时间(3000); }).然后(函数(结果){ $(“#结果”).append(结果+'@'+(新日期().getSeconds())+'
); });

jsFIDLE

调用和等待的格式有点不合适,您的
然后
应该是一个返回承诺的函数,因为现在您传递的是函数调用而不是函数,它会立即运行该请求,而不是因为承诺而等待调用函数

这应该做到:

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/>');
})
函数等待(超时){
返回新承诺(功能(解决、拒绝){
setTimeout(函数(){
解析(`Finished waiting${timeout}毫秒`);
},超时);
});
}
waitFor(1000)。然后(函数(解析、拒绝){
$(“#结果”).append(解析+'@'+新日期().getSeconds()++'
); }).然后(函数(){ 等待返回(2000年) }).然后(功能(解决、拒绝){ $(“#结果”).append(解析+'@'+新日期().getSeconds()++'
); }).然后(函数(){ 等待返回(2000年) }).然后(功能(解决、拒绝){ $(“#结果”).append(解析+'@'+新日期().getSeconds()++'
); })
您可以将承诺放入数组,并使用
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);
函数等待承诺(时间){
//console.log(时间);
返回新承诺((解决、拒绝)=>{
setTimeout(()=>{resolve('resolved');},时间);
});
}
功能日志(数据){
返回新承诺((解决、拒绝)=>{
log(数据+'@'+(新日期().getSeconds());
解决();
});
}
var ps=[];
对于(var i=0;i waitPromise(time));
ps.push(log);
}
log('started'+'@'+(new Date().getSeconds());
var p=Promise.resolve();
ps.reduce((p,c)=>{return p.then(c)},p);

这可能会有帮助-我甚至没有使用angularjs…我指向博客想了解一个想法-使用一个递归函数,它将遍历您的承诺数组。为什么只有一个返回?@MaxMastalerz initial
waitFor
返回initial
Promise
。然后()
在初始调用
waitFor(1000)之后
只需将承诺返回到最后一个
。然后()
很高兴能帮上忙,Max!请修复参数
解析,拒绝
。传递给
.then()
处理程序的是一个不应命名为
resolve
reject
的值。根据@jfriend00建议进行修复。