如果所有承诺都失败,如何等待几个HTTP承诺完成并显示模态

时间:2017-08-10 14:42:35

标签: javascript angularjs http promise

我在页面上有两个HTTP调用,它们是完全分开的。

vm.$onInit = function() {
    ....
    ....
    //Get all the items only once during initialization
    ds.getAllItems().then(function(result){
      vm.items = result;
     },function(error){
      vm.errorInApi = true;
    });
    .....
    .....
}
vm.getTimes = function(){
    .....
    .....
    HttpWrapper.send(url,{"operation":'GET'}).then(function(times){
                    .....
}

如果两个API都失败,那么我只需要显示一个模态。

我可以将变量设置为true并且在API失败时,我可以将其设为false,然后仅显示模态。

但是等待所有API的完成需要多长时间?

3 个答案:

答案 0 :(得分:1)

嗯......只需颠倒承诺的极性并使用Promise.all()

一旦所有承诺解决,

Promise.all()通常会解决,所以一旦承诺被反转,一旦所有承诺被拒绝,它就会解决......



var invert = p => new Promise((v, x) => p.then(x, v));

Promise.all([Promise.reject("Error 404"), Promise.reject("Error WTF")].map(invert))
       .then(v => console.log(v));




因此,根据@ guest271314评论,我用银勺扩展解决方案,以显示如何将反转承诺应用于此任务。



var invert = p => new Promise((v, x) => p.then(x, v)),
    prps   = [Promise.reject("Error 404"), Promise.reject("Error WTF")]; // previously rejected promises

myButton.addEventListener('click', function(e){
                                     setTimeout(function(...p){
                                                  p.push(Promise.reject("Error in Click Event Listener"));
                                                  Promise.all(p.map(invert))
                                                         .then(r => results.textContent = r.reduce((r,nr) => r + " - " + nr));
                                                }, 200, ...prps);
                                   });

<button id="myButton">Check</button>
<p id="results"></p>
&#13;
&#13;
&#13;

如果任何承诺(包括先前获得的承诺或事件处理程序中的一次承诺)得到解决,您将无法获得输出。

答案 1 :(得分:0)

您可以使用vm.$onInit = function() { .... .... return ds.getAllItems().then(function(result){ vm.items = result; },function(error){ vm.errorInApi = true; }); } vm.getTimes = function(){ ..... ..... return HttpWrapper.send(url,{"operation":'GET'}).then(function(times){ ..... }); }

首先,您应该在数组中获得两个promise。要实现这一点,如果您的两个函数返回它们创建的承诺,则可能很有用:

var arr = [];
arr.push(vm.$onInit());
...
arr.push(vm.getTimes());

然后将根据返回值构建数组:

getTimes

你写了一条评论,点击某个按钮就会调用Promise.all“,所以你可以在那里进行第二次推动。

或许,也许你会看到另一种方法来在数组中获得这些承诺......只要你实现了这一点,你的工作方式并不重要。

然后(在该点击处理程序中)您需要检测两个承诺都被拒绝的情况。 // Flip promises so that a rejected one is regarded as fulfilled and vice versa: arr = arr.map(p => p.then(res => { throw res }).catch(err => err)); // Detect that all original promises rejected, i.e. that the new promises all fulfill. Promise.all(arr).then(function() { // execute whatever you need to execute when both ajax calls failed }).catch(err => err); // ignore 可以做到这一点,但你需要翻转承诺结果:

current_track = Track.find(10)
random_track = Track.limit(1).order("RANDOM()").first

while random_track == current_track
  random_track = Track.limit(1).order("RANDOM()").first
  Rails.logger.debug "getting another random one..." random_track
end

答案 2 :(得分:0)

您可以使用async/await.catch()来确定拒绝Promise的数量,如果数字等于N则执行操作,其中N是被拒绝的数量{{1执行操作所需的值。

@trincot提到的先决条件是Promise来自函数的returnPromise来自传递给return的函数的值,.then() 1}}来自throw的{​​{1}}或Error()的第二个参数的函数,请参阅Why is value undefined at .then() chained to Promise?

.catch()
.then()