【问题标题】:Dynamic pushing to $q.all() promise array动态推送到 $q.all() 承诺数组
【发布时间】:2014-08-30 03:05:28
【问题描述】:
基本上,我正在尝试以 Angular 创建一个承诺队列,其工作方式类似于 $q.all(),除了它允许我将更多承诺推送到数组之后 $q.all() 已执行例如。
为了更好地解释,想象给一个函数一个单一的承诺,你想为then()执行一些代码。但是,当您等待第一个承诺解决时,您向该函数提供了第二个承诺。现在我不想在两者都完成之前调用then()(类似于$q.all())。如果第一个承诺在提供第二个承诺之前完成,则then() 函数将被调用两次。这应该适用于任意数量的 Promise。
基本上你最终会得到一个承诺队列,每次队列被清空时都会执行一次then()(即所有当前提供的承诺都已解决)。我确信我可以找到一个很好的方法来做到这一点,只需看看 SO 镇中是否有人已经实施了某些东西,或者我缺少一个简单的选项。
【问题讨论】:
标签:
javascript
angularjs
queue
angular-promise
【解决方案1】:
我遇到过类似的事情,也许会有所帮助。
我需要通过 AJAX 调用处理一棵树,以构建一个代表整个树的对象。当我进行 AJAX 调用时,它会给我有关子节点的数据,然后我必须进行 AJAX 调用以获取它们的数据。我需要在渲染它之前拥有整棵树,所以我需要知道何时完成。
$q.all 的问题是,是的,您可以向它传递一个 Promise 数组,但即使您稍后向数组添加更多 Promise,该数组也是固定的。
我(诚然 hacky)的解决方案是跟踪未答复请求的数量,如果有未完成的请求,则重做 $q.all。
var promisesArr = [];
var unresolved = 0;
function getChildNodes(node) {
var url = BASE_URL + '/' + node.id;
var prom = $q(function (resolve, reject) {
unresolved++;
$http.get(url).then(function (resp) {
angular.forEach(resp.data.children, function(v){
var newNode = {};
newNode.id = v.id;
getChildNodes(newNode);
node.children.push(newNode);
});
resolve();
unresolved--;
}, function () {
// Need to handle error here
console.log('ERROR');
reject();
unresolved--;
})
});
promisesArr.push(prom);
}
rootNode = {id: 1}
getChildNodes(rootNode);
allResolved();
function allResolved() {
if (unresolved > 0) {
$q.all(promisesArr).then(allResolved);
} else {
RenderTree(rootNode);
}
}