【问题标题】:JS - Run the promises in order with $q.when(), how do I add finally?JS - 使用 $q.when() 按顺序运行承诺,最后如何添加?
【发布时间】:2018-05-09 22:56:19
【问题描述】:

我正在使用外部源生成对象,目的是处理它们的回调样式。不幸的是,这些回调可能会超出浏览器的堆栈限制,我必须记住 IE 的最坏情况是 500。

我已经使用 $q.when 重写了我的代码

   $scope.combinations.forEach(function(combination) {
        chain = chain.then(function() {
         return generateConfiguration(combination);
        });
    });

generateConfiguration 如果一个函数返回一个承诺。这一切都很好,但我想做的是在链的末尾添加 finally()

到目前为止,我所做的是在 generateConfiguration 内部有一个跟踪器,它可以识别最后一个组合并触发应该由 finally 触发的内容。

有更清洁的方法吗?

【问题讨论】:

  • 循环后写chain.finally(…)

标签: javascript angular callback promise q


【解决方案1】:

这取决于你想做什么。

你正在创建一个承诺,所以如果你想要一个单个 finally 用于链,只需将它添加到末尾之后 strong> 用 forEach 构建它:

// ...your forEach here, then:
chain.finally(/*...*/);

如果您想要来自generateConfiguration每个 承诺上的finally,请给自己一个包装函数来执行此操作,或者在forEach 回调中执行此操作。

$scope.combinations.forEach(function(combination) {
    chain = chain.then(function() {
        return generateConfiguration(combination).finally(/*...*/); // <== 
    });
});

旁注:通过reduce,有一种更惯用的方式来构建该链:

var chain = $scope.combinations.reduce(function(chain, combination) {
    return chain.then(function() {
        return generateConfiguration(combination);
    });
}, Promise.resolve());

添加最终的finally(上面的选项#1):

var chain = $scope.combinations.reduce(function(chain, combination) {
        return chain.then(function() {
            return generateConfiguration(combination);
        });
    }, Promise.resolve())
    .finally(function() {
        // ...do stuff here...
    });

【讨论】:

  • @TJ 感谢您的初始解决方案有效。不知道为什么我还没有尝试过。关于您的建议,为什么它比我的解决方案更好?
  • @CountGradsky:除了它是过去 3-4 年出现的习惯用法之外,没有更好。 :-) 成语“好”或“更好”只是因为它们很容易被同样知道成语的其他程序员识别,从而使代码易于理解。
  • 不是母语人士,必须用谷歌搜索“惯用语”:) 如果您不介意,我会将您的建议作为评论
  • @CountGradsky:你的英语很好,我没注意到它不是你的母语。不过,恐怕我不明白你上面评论的后半部分。
  • 如果我离开 $q.when()
【解决方案2】:

是的,有:注入$q(即promise框架)并重写到

$q.all($scope.combinations.map(function(combination) {
   return generateConfiguration(combination);
})).finally(function(res) {
   /* ... */
});

这样,您还将并行触发所有 generateConfiguration(s)(至少尽可能多 - 例如 XHR 有限制)。无论如何:$q.all(arrayOfPromises) 可能是您一直在寻找的。​​p>

【讨论】:

  • 这不会改变代码的作用吗? OP 的代码串行处理承诺。 $q.all 不是并行处理吗(就像标准的Promise.all,我相信它是受q's 启发的)?
  • 是的,正如我所说,它确实并行处理它们。如果这真的不需要,我会在 .chain 的最后一个值上调用 .finally (就像另一个答案中已经建议的那样)
猜你喜欢
  • 2020-06-16
  • 2018-09-03
  • 1970-01-01
  • 1970-01-01
  • 2017-07-14
  • 2021-11-29
  • 1970-01-01
  • 2019-06-16
  • 2013-12-04
相关资源
最近更新 更多