2016-05-16 64 views
3

我有一组承诺,每个承诺都调用http.get()

var items = ["URL1", "URL2", "URL3"]; 
var promises = []; 
//on each URL in items array, I want to create a promise and call http.get 
items.forEach(function(el){ 
    return promises.push($http.get(el)); 
}); 
var all = $q.all(promises); 
all.then(function success(data){ 
    console.log(data); 
}).catch(function(reason){ 
    console.log("reason is", reason); 
}); 

发生的事情在我的情况

URL2.get没有得到解决,并立即触发了$q.allcatch()。由于此故障all.then()永远不会被调用。

我想

我希望所有的承诺,继续即使承诺一个被拒绝。

我找到了一个类似的post,但解决方案建议使用另一个叫做的Kris Kowal的Q。所以我想知道如何在不使用外部包的情况下实现它?

+0

见http://stackoverflow.com/questions/31424561/wait-直到所有es6承诺,完成,甚至拒绝承诺/ – guest271314

+0

@ guest271314谢谢你会看看 –

+0

我不知道为什么有人downvoted这个问题? –

回答

7

一个简单的黑客可能会增加一个catch块返回空的承诺,并从你promise.all结果过滤无效的结果,是这样的:

let items = ["URL1", "URL2", "URL3"] 
    , promises = items.map(url => $http.get(url).catch(e => null)) 
    , all = $q.all(promises).then(data => data.filter(d => !!d)) 

all.then(data => { 
    // do something with data 
}).catch(e => { 
    // some error action 
}) 

在ES5同样的事情:

var items = ["URL1", "URL2", "URL3"] 
    , promises = items.map(function(url){ 
    return $http.get(url).catch(function(e){return null}) 
    }) 
    , all = $q.all(promises).then(function(data){ 
    return data.filter(function(d){return !!d}) // filter out empty, null results 
    }) 

all.then(function(data){ 
    // do something with data 
}).catch(function(e){ 
    // some error action 
}) 
2

这里是一个兼容版本.settle()的ES6,允许所有的承诺完成,然后你可以查询每个结果,看看它是成功还是失败:

// ES6 version of settle 
Promise.settle = function(promises) { 
    function PromiseInspection(fulfilled, val) { 
     return { 
      isFulfilled: function() { 
       return fulfilled; 
      }, isRejected: function() { 
       return !fulfilled; 
      }, isPending: function() { 
       // PromiseInspection objects created here are never pending 
       return false; 
      }, value: function() { 
       if (!fulfilled) { 
        throw new Error("Can't call .value() on a promise that is not fulfilled"); 
       } 
       return val; 
      }, reason: function() { 
       if (fulfilled) { 
        throw new Error("Can't call .reason() on a promise that is fulfilled"); 
       } 
       return val; 
      } 
     }; 
    } 

    return Promise.all(promises.map(function(p) { 
     // make sure any values or foreign promises are wrapped in a promise 
     return Promise.resolve(p).then(function(val) { 
      return new PromiseInspection(true, val); 
     }, function(err) { 
      return new PromiseInspection(false, err); 
     }); 
    })); 
} 

这可以适应用于Q库这样的:

// Q version of settle 
$q.settle = function(promises) { 
    function PromiseInspection(fulfilled, val) { 
     return { 
      isFulfilled: function() { 
       return fulfilled; 
      }, isRejected: function() { 
       return !fulfilled; 
      }, isPending: function() { 
       // PromiseInspection objects created here are never pending 
       return false; 
      }, value: function() { 
       if (!fulfilled) { 
        throw new Error("Can't call .value() on a promise that is not fulfilled"); 
       } 
       return val; 
      }, reason: function() { 
       if (fulfilled) { 
        throw new Error("Can't call .reason() on a promise that is fulfilled"); 
       } 
       return val; 
      } 
     }; 
    } 

    return $q.all(promises.map(function(p) { 
     // make sure any values or foreign promises are wrapped in a promise 
     return $q(p).then(function(val) { 
      return new PromiseInspection(true, val); 
     }, function(err) { 
      return new PromiseInspection(false, err); 
     }); 
    })); 
} 

使用与您的特定代码:

var items = ["URL1", "URL2", "URL3"]; 
$q.settle(items.map(function(url) { 
    return $http.get(url); 
})).then(function(data){ 
    data.forEach(function(item) { 
     if (item.isFulfilled()) { 
      console.log("success: ", item.value()); 
     } else { 
      console.log("fail: ", item.reason()); 
     } 
    }); 
}); 

注:.settle()返回一个承诺,始终解析,从不拒绝。这是因为无论您通过多少承诺都拒绝,它仍然可以解决,但会返回您通过承诺的信息可以解决或拒绝。

0

我裹在$ Q $的资源,只有解决状态

var promises = [ 
    $q(function (resolve) { 
     Me.get({params: 12}).$promise.then(function (data) { 
      resolve(data); 
     }, function (err) { 
      resolve(err); 
     }); 
    }), 
    $q(function (resolve) { 
     Me.get({params: 123}).$promise.then(function (data) { 
      resolve(data); 
     }, function (err) { 
      resolve(err); 
     }); 
    }), 
    $q(function (resolve) { 
     Me.get({params: 124}).$promise.then(function (data) { 
      resolve(data); 
     }, function (err) { 
      resolve(err); 
     }); 
    })]; 

,然后使用$ q.all诺言