简短的问题是:对于多个并发承诺,如何在所有承诺成功或失败后最终发生某些事情? (而不是在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 }
返回可以观察到进度的承诺,那么它可以用于完全需要的东西。我们只需要显示或隐藏旋转轮取决于pending
是0
是否真的很简单。
一种简单的方法就是拥有一个计数器来计算"活跃的"方形面板。当每个面板开始数据提取时,递增计数器,并在取回成功或失败时,然后递减计数器,但如果它是一个浮动的全局变量,则可能不那么干净。
另一种方法可能是构建一个overallPanel对象,它"有" (意思是组成)16个squarePanel对象,每个squarePanel都需要是一个可观察对象本身,这样整个面板就会在每个上面观察,并递增或递减一个计数器,并在计数器时显示旋转轮> 0,并且当counter == 0时隐藏。(因此,当每个squarePanel成功或失败以获取数据时,它将依次解析或拒绝自身,以便通知观察者,这是整个面板)
或者有没有办法使用内置的Promise或Deferred函数?
答案 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);
});
同时处理好的和坏的结果。无需实现自己的逻辑来计算承诺。