【问题标题】:For loops with promises带有承诺的 for 循环
【发布时间】:2016-06-25 07:22:23
【问题描述】:

我想写三个 for 循环,承诺如下:

for i = 1 .. 3
 for j = 1 .. 5
  for k = 1 .. 6
   post call to db to check if there is item on location i, j, k
  • 第 1 步:检查 1,1,1
  • 第 2 步:检查 1,1,2 项是否找到或包含下一个索引
  • ...

我搜索了类似的问题,但只得到一维数组循环示例。

我发现了这个非常困难的问题,我希望你们能帮助我。谢谢。

【问题讨论】:

  • 这不仅含糊不清,无法合理回答,而且被误导了。 Promise 是异步的,for 循环不是。你不能只是“等待”承诺解决。
  • @Claise:是的,我在这里用错了词,对不起。 jfriend00 在下面的答案中解释了我的问题是什么:)

标签: angularjs node.js


【解决方案1】:

管道承诺可以线性完成。因此,在您的情况下,您必须首先生成一个包含所有可能组合的数组,如下所示:

$locations = [
    [1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 1, 4],
    ....  
];

然后您可以轻松地循环遍历这个数组并管道化您的承诺。希望这会有所帮助

【讨论】:

    【解决方案2】:

    您不能将同步的for 循环与异步操作结合起来并让事情正确排序,因为没有办法让for 循环“等待”承诺完成。 for 循环同步运行,因此它会立即启动所有异步操作。

    因此,您必须以另一种方式进行迭代。如果您只迭代一个参数,则有许多现成的方法可以做到这一点,但我不知道有任何用于迭代三个嵌套变量的预构建解决方案,因此您必须构建自己的。这是一种方法。此方法是为您的迭代自定义编码的,这使得它的代码比一般方案少:

    // fn gets called like this fn(i, j, k) and must return a promise
    function iterateLevels(fn) {
        var i = 1, iMax = 3;
        var j = 1, jMax = 5;
        var k = 1, kMax = 6;
    
        function next() {
            if (k > kMax) {
                j++;
                k = 1;
            }
            if (j > jMax) {
                i++;
                j = 1;
            }
            if (i > iMax) {
                return;
            }
            return fn(i, j, k).then(function(result) {
                k++;
                // process result here
    
                // if you want to continue processing, then
                return next();
            });
        }
        return next();
    }
    

    这是一个使用带有随机延迟的承诺的工作演示实现:https://jsfiddle.net/jfriend00/q2Lnhszt/

    具有外部作用域变量ijknext() 函数本质上是一个状态机,每次调用next() 时它都会运行下一次迭代并更新其状态。

    这可以是通用的,因此您可以传入多少个迭代级别以及每个级别的开始和停止值是什么,并且您可以传入一个函数来处理结果。使其通用化会为实现添加更多代码,并使逻辑更难遵循。

    【讨论】:

      猜你喜欢
      • 2019-08-17
      • 2015-12-18
      • 2013-06-17
      • 1970-01-01
      • 2023-03-17
      • 2017-07-18
      相关资源
      最近更新 更多