如何在" AND"中结合延迟/承诺关系,但不要将单个拒绝计为总体拒绝?

时间:2016-01-09 11:32:33

标签: javascript promise angular-promise jquery-deferred deferred

简短的问题是:对于多个并发承诺,如何在所有承诺成功或失败后最终发生某些事情? (而不是在1个承诺失败后做某事)。

我认为它适用于jQuery Deferreds或AngularJS Deferreds,并且要求是,让我们说屏幕上有16个方形面板,布局为4 x 4网格。

用户可以点击"获取"或者"刷新"刷新每个方框面板,将为该特定面板提取数据。

所以这是一个简单的承诺情况:16个承诺。

然而,如果是全球"纺车"例如,在视口的右上角需要。即使单个方形面板等待数据,它也会显示出来,同样如果2个,3个或更多个面板正在等待数据。当所有数据提取成功或失败时,旋转轮应该消失。但关键是,当单个数据提取失败时,它不应该考虑整个操作失败并立即隐藏旋转轮。

有没有办法使用$.when()$.pipe()来完成这项工作? $.when()似乎是" AND"关系,但任何一个失败的提取将使操作被认为完全失败并立即隐藏纺车。我们可以使用$.when()作为新承诺,因此可以某种方式使用它来报告"进展&#34 ;? (但是如何?)。 (实际上,如果when()可以使用数据{ total: 8, success: 3, fail: 1, pending: 4 }返回可以观察到进度的承诺,那么它可以用于完全需要的东西。我们只需要显示或隐藏旋转轮取决于pending0是否真的很简单。

一种简单的方法就是拥有一个计数器来计算"活跃的"方形面板。当每个面板开始数据提取时,递增计数器,并在取回成功或失败时,然后递减计数器,但如果它是一个浮动的全局变量,则可能不那么干净。

另一种方法可能是构建一个overallPanel对象,它"有" (意思是组成)16个squarePanel对象,每个squarePanel都需要是一个可观察对象本身,这样整个面板就会在每个上面观察,并递增或递减一个计数器,并在计数器时显示旋转轮> 0,并且当counter == 0时隐藏。(因此,当每个squarePanel成功或失败以获取数据时,它将依次解析或拒绝自身,以便通知观察者,这是整个面板)

或者有没有办法使用内置的Promise或Deferred函数?

1 个答案:

答案 0 :(得分:2)

好吧,就像你说的那样,你有$.when$q.all,它们都是本地(和蓝鸟)承诺的有效Promise.all

您缺少的是reflect原语,可将拒绝转换为履行,并以某种方式表明所述失败:

var res = Promise.all(promises.map(x => x.then(v => ({v, good: true}), 
                                               e => ({e, bad: true})));

可以让你这样做:

res.then(results => {
   let good = results.filter(x => x.good);
   let bad = results.filter(x => x.bad);
});

同时处理好的和坏的结果。无需实现自己的逻辑来计算承诺。