Javascript promise 递归和链接

标签 javascript loops recursion promise chaining

我应该如何编写递归循环才能按顺序正确执行 promise ?我尝试过 Promise.all(Array.map(function(){}));这不适合我的需要,因为这些步骤需要按顺序运行。我尝试过自定义 promise ,因为我发现 here ,但它也有问题。

promise :

var promiseFor = (function(condition, action, value) {
    var promise = new Promise(function(resolve, reject) {
        if(!condition(value)) {
            return;
        }
        return action(value).then(promiseFor.bind(null, condition, action));
    });
    return promise;
});

这个 for 的问题是它似乎停在最深的递归调用处,而不是返回继续执行循环以正确完成。

例如:在 PHP 中,代码如下:

function loopThrough($source) {
    foreach($source as $value) {
        if($value == "single") {
            //do action
        } else if($value == "array") {
            loopThrough($value);
        }
    }
}

如果我通过了一个文件夹结构,“单个”表示文件,它将打印所有文件。但我正在使用的 promise 在第一个死胡同中停止了。

编辑:添加了 bluebird ,看看它是否可以帮助解决任何问题,仍然是同样的事情。 这是当前循环代码

var runSequence = (function(sequence, params) { 
    return Promise.each(sequence, function(action) {
        console.log(action['Rusiavimas'] + ' - ' + action['Veiksmas']);
        if(params.ButtonIndex && params.ButtonIndex != action['ButtonIndex']) {
            return Promise.resolve();
        }

        if(action['Veiksmas'].charAt(0) == '@') {
            var act = action['Veiksmas'];
            var actName = act.substr(0, act.indexOf(':')).trim();
            var actArg = act.substr(act.indexOf(':')+1).trim();

            /* This one is the code that figures out what to do and
               also calls this function to execute a sub-sequence. */
            return executeAction(actName, actArg, params);
        } else {
            sendRequest('runQuery', action['Veiksmas']);
        }
    });
});

我有 3 个序列,每个序列包含 5 个 Action 。第一个和第二个序列将下一个序列作为第三个 Action 。这是我得到的结果(数字表示哪个序列):

1 - @PirmasVeiksmas
1 - @AntrasVeiksmas
1 - @Veiksmas: list_two
2 - @PirmasVeiksmas
2 - @AntrasVeiksmas
2 - @Veiksmas: list_three
3 - @PirmasVeiksmas
3 - @AntrasVeiksmas
3 - @TreciasVeiksmas
3 - @KetvirtasVeiksmas
3 - @PenktasVeiksmas

正如您所看到的,它进入下一个序列并按应有的方式继续,但是一旦第三个序列完成,它应该恢复第二个序列并完成第一个序列。但一旦遇到递归的第一个死胡同,它就会停止。

编辑2:我现在拥有的Codepen示例以及正在发生的事情的视觉表示:Codepen link

输出应该是:

fa1
second
sa1
third
ta1
ta2
ta3
sa3
fa3

最佳答案

可以使用 .reduce() 而不是 .map() 来按顺序运行一堆操作。

这是一个例子:

// Helper function that creates a Promise that resolves after a second
const delay = (value) => new Promise(resolve => setTimeout(() => resolve(value), 1000));

const arr = [1, 2, 3, 4, 5];

// concurrent resolution with `.map()` and `Promise.all()`
Promise.all(arr.map(delay))
  .then(console.log.bind(console)); // [1, 2, 3, 4, 5] after a second.

// sequential resolution with `.reduce()`

arr.reduce((promise, current) => 
             promise
               .then(() => delay(current))
               .then(console.log.bind(console)), 
           Promise.resolve());
// second wait, 1, second wait, 2...

如果我正确理解了您的要求,那么您并不完全需要 Promise 递归,这只是您发现顺序运行 Promise 的方式。 .reduce() 可以更简单地帮助您。

归约过程将[1,2,3,4,5]变成:

Promise.resolve()
  .then(() => delay(1))
  .then(console.log.bind(console))
  .then(() => delay(2))
  .then(console.log.bind(console))
  .then(() => delay(3))
  .then(console.log.bind(console))
  .then(() => delay(4))
  .then(console.log.bind(console))
  .then(() => delay(5))
  .then(console.log.bind(console))

请注意,如果您想访问所有结果,则需要做更多的工作。但我会将其作为练习留给读者:)

关于Javascript promise 递归和链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36353344/

相关文章:

javascript - AngularJS + 简易饼图 - 动画不工作

java - 无法对以下 TreeMap 进行排序

python - 更优雅地改变数组的数组

perl - 如何在 Perl 中创建所有大小小于 n 的子集?

java - 是否有将迭代解决方案转换为递归解决方案的通用公式?

JavaScript:意外的标记

Javascript amcharts 堆积条形图单击处理程序

python - 递归函数运行时间分析

file - 如何使用 PowerShell 删除空子文件夹?

javascript - 从另一个功能打开弹出窗口 - Magnific Popup