嵌套承诺实现顺序执行
Nested promises to achieve sequential execution
我有一个函数,当一个承诺被解析时,它会调用自己几次,当它完成调用自身时,它会像这样解析承诺:
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()
并在解析它返回的承诺时继续执行。
function executeAllSteps() {
runStep().then(
function(){
console.log("resolved outer promise");
});
}
我的问题是我无法使executeAllSteps
功能按预期工作。我已经为.then
尝试了几种语法,但没有产生所需的输出。
要么立即调用内容,而不解决承诺(当我这样写时:runStep().then(console.log("resolved outer promise"));
,或者根本不调用。
有谁知道如何纠正此功能?
注意:我需要使用原生的javascript承诺实现。
一旦你进入if (counter < reference ) {
条件,你将永远无法解决你在runStep()
调用中创建的承诺,因此executeAllSteps()
中的.then()
处理程序永远不会触发。 你需要在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");
}
});
}
从逻辑上讲,这将调用将执行somePromiseReturningFunction()
的第一个runStep()
,当它完成时(当它的承诺被解析时(,它将调用一个嵌套runStep()
当内部runStep
解析时,外部将自行解析。 因此,将要发生的事情是,您将嵌套多个调用以runStep()
,直到您的counter
达到reference
值,然后该内部runStep
将自行解决。 这将允许下一个最外在的runStep
自行解析,然后下一个最外在的runStep
继续解析自身,直到它到达最外在的runStep
,它将自行解析,然后.then()
executeAllSteps()
的处理程序听起来是你想要的。
我
怀疑如果我更多地了解你真正想要完成的事情,而不是这个有点抽象的代码示例,那么我可能会找到一种更干净的方法来做到这一点,但我并没有真正遵循你想在什么条件下做什么。
您可以采取几种不同的方法,使用现有承诺,而不是总是创建新承诺。 这里有一个想法:
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");
});
}
}
您还可以避免在计数器达到其值时递归调用 runStep,这稍微简化了事情(假设当计数器已经超过该值时,您第一次不调用 runStep(:
var counter = 0;
function runStep(past_resolved_content) {
counter++;
return somePromiseReturningFunction().then(function(data) {
if (counter < reference) {
return runStep(data);
} else {
return data;
}
});
}
这个想法的工作演示:http://jsfiddle.net/jfriend00/PfEV2/
而且,如果你不需要在过程展开时操作counter
变量,那么你也可以在循环中进行操作,runStep
不必调用自己,计数器也不必是公共变量:
function runStep() {
var p = Promise.resolve();
for (var counter = 0; counter < reference; counter++) {
p = p.then(somePromiseReturningFunction);
}
return p;
}
工作演示:http://jsfiddle.net/jfriend00/33ZZ6/
- javascript函数和代码隐藏函数的执行顺序
- Node.js:多个然后'It’执行顺序不正确
- 不同'单击'不同脚本中的回调:我可以控制执行顺序吗
- 代码混淆的执行顺序
- Javascript执行顺序错误
- Javascript执行顺序和回调
- 奇怪的javascript代码执行顺序
- for 循环/递归中的执行顺序
- JavaScript 中的执行顺序问题
- 来自函数 Javascript 的 NaN 返回值 ||函数执行顺序
- 控制承诺执行顺序
- 我可以信任 JavaScript 中声明中的执行顺序吗?
- 使用webcomponenetsjs的HTMLImports以意外的执行顺序加载导入-firefox
- 确保执行顺序:javascript
- Javascript代码的执行顺序
- 保证HTML表单提交和jQuery onclick的执行顺序
- 在ASP.Net中运行javascript时的执行顺序
- jQuery函数执行顺序
- Javascript中绑定到事件的函数的执行顺序
- 淘汰js可观察扩展的执行顺序是什么