嵌套承诺实现顺序执行

时间:2014-07-22 15:46:07

标签: javascript nested promise

我有一个函数,当一个promise被解决时,它自己调用了几次,当它完成调用时,它就像这样解决了这个承诺:

var counter = 0;
function runStep(past_resolved_content) {
  return new Promise(function(resolve, reject){
  //do something different with counter
  if (counter < reference ) {
    counter++;
    var step_ran = somePromiseReturningFunction();
    step_ran.then(runStep);
  } else {
    resolve("message");     
  }

据我所知,该功能可以实现我想要的功能,它将按正确的顺序正确调用somePromiseReturningFunction()。 我有第二个函数必须调用runStep()并在解析它返回的promise时继续执行。

function executeAllSteps() {
  runStep().then(
    function(){
      console.log("resolved outer promise");
  });
}

我的问题是我无法使executeAllSteps功能按预期工作。我已经为.then尝试了几种语法,但没有产生所需的输出。

要么立即调用内容,要么不解析承诺(当我这样写时:runStep().then(console.log("resolved outer promise"));,或者根本不会。

有谁知道如何更正此功能?

注意:我需要使用本机javascript promise实现。

1 个答案:

答案 0 :(得分:0)

进入if (counter < reference ) {条件后,您永远无法解决在runStep()调用中创建的承诺,因此.then()中的executeAllSteps()处理程序永远不会触发。您需要在runStep()中找到一个位置,您可以在其中解析为runStep()的每次调用创建的承诺,无论您是否达到了最大值。

我不确定我是否完全理解你想要实现的目标,但你可以这样做:

var counter = 0;
function runStep(past_resolved_content) {
  return new Promise(function(resolve, reject) {
    //do something different with counter
    if (counter < reference ) {
      counter++;
      var step_ran = somePromiseReturningFunction();
      step_ran.then(runStep).then(resolve);          // <== change made here
    } else {
      resolve("message");     
    }
  });
}

逻辑上,这将调用第一个执行runStep()的{​​{1}}并在完成时(当它的承诺得到解决时),它将调用嵌套的somePromiseReturningFunction()并且当它内部runStep()结算,外部将自行解决。那么将会发生几次调用runStep,直到runStep()获得counter值,然后内部reference将自行解决。这将允许下一个最外层的runStep自行解决,然后下一个最外层的runStep自行解决,直到它到达最外层runStep,这将自行解决,然后全部然后在runStep.then()处理程序听起来就像你想要的那样。


我怀疑,如果我更了解你真正想要完成的事情,而不是这个有点抽象的代码示例,那么我可能会找到一个更清洁的方法来做到这一点,但我并不真正遵循你想要的在什么条件下做。


您可以采用几种不同的方法来使用现有的承诺,而不是总是创建新的承诺。这是一个想法:

executeAllSteps()

当计数器达到其值时,你也可以避免递归地调用runStep,这样可以简化一些事情(假设你在计数器已经超过这个值时第一次没有调用runStep):

var counter = 0;
function runStep(past_resolved_content) {
    //do something different with counter
    if (counter < reference ) {
        counter++;
        return somePromiseReturningFunction().then(runStep);
    } else {
        // return a resolved promise with your message
        return Promise.resolve("message");
        });
    }
}

这个想法的工作演示:http://jsfiddle.net/jfriend00/PfEV2/


而且,如果您不需要在过程展开时操纵var counter = 0; function runStep(past_resolved_content) { counter++; return somePromiseReturningFunction().then(function(data) { if (counter < reference) { return runStep(data); } else { return data; } }); } 变量,那么您也可以在循环中执行此操作counter无需调用自身和计数器不必是公共变量:

runStep

工作演示:http://jsfiddle.net/jfriend00/33ZZ6/