一个数组,并删除项目,如果条件满足于JavaScript .MAP [英] JavaScript .map on an array and removing items if condition satisfied

查看:159
本文介绍了一个数组,并删除项目,如果条件满足于JavaScript .MAP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数组队列我推对象,它被修改时。如果用户presses 保存,那么我会通过队列循环并应用适当的API调用他们。

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 and apply the appropriate API call for them.

如果API调用经过成功的,我想删除从队列的项目,否则保持它的内部并通知一些项目未成功保存的用户。目前,我有这个(在AngularJS)

If the API call goes through successfully, I want to remove the item from the queue, otherwise keep it inside and notify the user that some items were not successfully saved. I currently have this (in AngularJS)

var unsuccessfulItems = [];
var promise = queue.map(function(item) {
    var defer = $q.defer();
    myCallFunction( item
           , function( response ) {} // Success
           , function( response ) {  // Error
               unsuccessfulItems.push(item);
           }
    )
    defer.resolve();
    return defer.promise;
})
// Once all items have been processed
$q.all( promise ).then( function() {
    queue = unsuccessfulItems;
});

是否有这样做的更好的办法?

Is there a better way of doing this?

推荐答案

您已经在使用的承诺,你可能会想这样做终端到终端。此外,你解决的承诺为时尚早。

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

假设不理想的情况下,你不想promisify myCallFunction 本身,你还是应该promisify它。

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.

现在,我们需要实现一个摆平功能,当所有的承诺都不管做一个解析。这就好比 $ q.all ,但将等待所有的承诺来解决,而不是履行。

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.
             }
         });
     });
}

这类结算功能的最有希望实现中存在,但不是在 $ Q 。我们可以用拒绝也这样做, $ q.all ,但是这意味着流量控制这是一个不好的做法例外。

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.

现在,我们可以通过结算

 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; });
 });

这篇关于一个数组,并删除项目,如果条件满足于JavaScript .MAP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆