JavaScript .map on an array and removing items if condition satisfied

前端 未结 2 503
日久生厌
日久生厌 2020-12-11 05:36

I have an array queue that I push objects to it when they are modified. If the user presses save, then I will loop through the queue a

2条回答
  •  情话喂你
    2020-12-11 06:23

    You're already using promises, you might want to do it end-to-end. Also, you're resolving the promise too early.

    Assuming the suboptimal case where you don't want to promisify myCallFunction itself, you should still promisify it.

    function myCall(item){
        var d = $q.defer();
        myCallFunction(item,function(r){ d.resolve({val:r,item:item});}
                           ,function(r){ d.reject(r);});
        return d.promise;
    }
    

    Note, we are resolving the defer after the asynchronous function is done, not before it.

    Now, we need to implement a "Settle" function, that resolves when all promises are done no matter what. This is like $q.all but will wait for all promises to resolve and not fulfill.

    function settle(promises){
         var d = $q.defer();
         var counter = 0;
         var results = Array(promises.length);
         promises.forEach(function(p,i){ 
             p.then(function(v){ // add as fulfilled
                  results[i] = {state:"fulfilled", promise : p, value: v};
             }).catch(function(r){ // add as rejected
                  results[i] = {state:"rejected", promise : p, reason: r};
             }).finally(function(){  // when any promises resolved or failed
                 counter++; // notify the counter
                 if (counter === promises.length) {
                    d.resolve(results); // resolve the deferred.
                 }
             });
         });
    }
    

    This sort of settle function exists in most promise implementations but not in $q. We could have also done this with rejections and $q.all, but that would mean exceptions for flow control which is a bad practice.

    Now, we can settle:

     settle(queue.map(myCall)).then(function(results){
         var failed = results.filter(function(r){ return r.state === "rejected"; });
         var failedItems = failed.map(function(i){ return i.value.item; });
     });
    

提交回复
热议问题