4

基本上,我正在尝试以 Angular 创建一个类似的 Promise 队列,除了它允许我在执行后将$q.all()更多 Promise 推送到数组上。 $q.all()

为了更好地解释,想象给一个函数一个你想要执行一些代码的单一承诺then()。但是,当您等待第一个承诺解决时,您向该函数提供了第二个承诺。现在我不想then()在两者都完成之前被调用(类似于$q.all())。如果第一个 Promise 在提供第二个 Promise 之前完成,则该then()函数将被调用两次。这应该适用于任意数量的承诺。

本质上,您最终会得到一个承诺队列,then()每次队列被清空时都会执行一次(即所有当前提供的承诺都已解决)。我确信我可以找到一个很好的方法来做到这一点,只是看看 SO 镇上是否有人已经实施了某些东西,或者我缺少一个简单的选择。

4

1 回答 1

0

我遇到了类似的事情,也许会有所帮助。

我需要通过 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);
        }
    }
于 2017-04-14T14:21:31.647 回答