使用迭代和异步调用递归

时间:2014-01-18 12:59:51

标签: javascript asynchronous recursion promise jquery-deferred

我有一个我想要迭代的数组,根据它的长度,进行异步调用以获取我想要添加到新数组的一些数据。

伪代码如下:

var path =["Cars", "Owners", "Name"];
var parentObject = mainObject;

getChildren (path, parentObject){
    var deferred = new JQuery.Deferred();
    var pathSplit = path.split(".");
    var nestedObjectName = pathSplit[0];
    var childrenIds = new Array();
    if (pathSplit.length = 2){
        return deferred.resolve(parentObject.Id);
    }
    else{
        nestedObject = parentObject[nestedObjectName];
        pathSplit.shift();
        var promises = [];
        for (child in nestedObjects.children){                      //iteration
            promises.push(
                asyncCalltoGetDetails(child).then{ //After this line, the promises array resolves. !?!?!
                    getChildren(pathSplit, child).then(function(childId){   //recursivity
                        childrenIds.push(childId);
                    });     
                }           
            );
        }
        JQuery.when.apply(null, promises).then(function(){
            return deferred.resolve(childrenIds);
        });
    }
    return deferred.promise();
}

当我使用异步调用进行迭代时,我使用promises [],如下所述:How do you work with an array of jQuery Deferreds?

当我使用异步方法使用递归调用时,我使用延迟对象传递所有方法。如下所述:AngularJS, promise with recursive function

我遇到的问题是,当asyncCalltoGetDetails发生时,promises会解析,但我想在递归的getChildren返回deferred.resolve()时解析它;

知道我做错了什么吗?如何正确使用promises []和延迟对象的技术在同一方法中迭代?

谢谢你的时间!

1 个答案:

答案 0 :(得分:1)

  

我遇到的问题是,当asyncCalltoGetDetails发生时,promises会解析,但我想在递归的getChildren返回deferred.resolve()时解析它;

你有点滥用deferred,但它应该有效。如果promise在asyncCalltoGetDetails完成其工作之前解析,则需要在该函数中搜索错误。

  

知道我做错了吗?

它可能只是你的伪代码,但这看起来很麻烦:

promises.push(
    asyncCalltoGetDetails(child).then{ //After this line, the promises array resolves. !?!?!
        getChildren(pathSplit, child).then(function(childId){   //recursivity
            childrenIds.push(childId);
        });     
    }           
);

then确实需要一个函数,所以我猜你给了它一个函数表达式。那你的意思是哪一行 - then正在执行而不是它的回调,回调正在执行而不是等待getChildren

对于后者,解决方案是then,当用于操作链接(编写承诺加上对新承诺的回调)时,允许您从回调中返回承诺。这就是这里缺少的 - return声明!如果您只是致电getChildren,其结果将永远不会在任何地方使用,则回调只会返回undefined


另外,为了正确使用promises,这很难看:

    JQuery.when.apply(null, promises).then(function(){
        return deferred.resolve(childrenIds);
    });
}
return deferred.promise();

停止使用“helper”数组childrenIds(来自异步回调)!停止手动创建deferred - 您甚至不会拒绝它!相反,将子ID设为promises的结果值,并使用then-callbacks 的参数。

检查我对Understanding promises in node.js for recursive functionIs there an example of using raw Q promise library with node to recursively traverse a directory asynchronously?的回答 - 即使他们没有使用jQuery的实现,他们应该会告诉你如何做到这一点。