函数“返回”未分配给变量

时间:2014-03-17 16:00:28

标签: javascript jquery

我编写了一个函数,通过递归搜索对象来获取所有特定元素,并返回结果元素数组。

该功能本身运作完美,但由于某种原因,"返回" part不会被赋值给调用函数的变量。

这是函数本身:

var getLinksInObject = function(object){
    // Define Variables
    var allLinks = [];
    var getLinksTimeout = null;

    // Function to get the links in an object. Called recursively
    var getLinks = function(object){
        // Get category and link links
        var categories = object.categories;
        var links = object.links;

        // If there are links
        if (links && links.length > 0){
            // Push each of them to the allLinks array
            for (var i=0, j=links.length; i<j; i++){
                allLinks.push(links[i]);
            };
        };

        // If there are category links, push them to the allLinks array
        if (categories && categories.length > 0){
            for (var i=0, j=categories.length; i<j; i++){
                // Build the link
                var link = {
                    title: categories[i].title,
                    link: categories[i].link
                };
                // Push the link to allLinks
                allLinks.push(link);

                // If there are sub-links, run getLinks on that object to get the next level of links
                if (categories[i].categories) {
                    // Reset the listener so it knows we are going for another round
                    resetTimeout();

                    // Get the links in the next level
                    getLinks(categories[i]);
                }           
            };
        };
    };

    // Listens for when the recursive calls finish and returns the result
    var resetTimeout = function(){
        clearTimeout(getLinksTimeout);
        getLinksTimeout = setTimeout(function(){
            log(allLinks);
            return allLinks;
        }, 50);
    };

    resetTimeout();
    getLinks(object);
};

这是一个运行它的测试对象,它匹配实际对象的结构:

{
    link: "http://test.com",
    title: "This is a test",
    categories: [
        {
            link: "http://test.com",
            title: "This is a test",
            categories: [
                {
                    link: "http://test.com",
                    title: "This is a test",
                    categories: [
                        {

                        }
                    ]
                }
            ]
        },
        {
            link: "http://test.com",
            title: "This is a test",
            categories: [
                {
                    link: "http://test.com",
                    title: "This is a test",
                    categories: [
                        {
                            link: "http://test.com",
                            title: "This is a test",
                            categories: [
                                {
                                    link: "http://test.com",
                                    title: "This is a test"
                                }
                            ]
                        }
                    ]
                },
                {
                    link: "http://test.com",
                    title: "This is a test",
                    categories: [
                        {

                        }
                    ]
                },
                {
                    link: "http://test.com",
                    title: "This is a test",
                    categories: [
                        {

                        }
                    ]
                }
            ]
        },
        {
            link: "http://test.com",
            title: "This is a test",
            categories: [
                {
                    link: "http://test.com",
                    title: "This is a test",
                    categories: [
                        {

                        }
                    ]
                }
            ]
        }
    ]
}

这是一个重复问题的小提琴。您将能够在控制台中看到问题,因为记录了&#34;结果&#34;以未定义的方式注销。

http://jsfiddle.net/KS7LG/

3 个答案:

答案 0 :(得分:2)

您分配给getLinksInObject的功能没有return声明。它将始终返回undefined

整个代码中唯一的return语句是:

setTimeout(function(){
console.log(allLinks);
    return allLinks;
}, 50);

setTimeout正在调用该函数,setTimeout不会关注它调用的函数的任何返回值。

setTimeout是异步的,它稍后运行代码 并且不会阻止从继续调用它的函数。如果你想处理在时间用完之后生成的数据,那么你必须从你传递的函数开始前进,现在回传数据为时已晚。

答案 1 :(得分:1)

Javascript(主要)同步运行,因此您不需要任何timeout相关代码来使function正常工作。在计算时立即返回值就可以了。

请参阅:jsFiddle

特别是,以下变化:

              //resetTimeout(); <- remove this

                // Get the links in the next level
                getLinks(categories[i]);
            }           
        };
    };
};

//removed timeout code

getLinks(object);
return allLinks;

答案 2 :(得分:0)

返回将无法与setTimeout一起使用,因为它是异步的。您需要创建一个回调来实现您想要的目标:

var getLinksInObject = function(object, callback) {
    // ...            
    var resetTimeout = function(){
        clearTimeout(getLinksTimeout);
        getLinksTimeout = setTimeout(function(){
            log(allLinks);
            callback(allLinks);
        }, 50);
    };

   // ...
};

然后您必须修改getLinksInObject电话:

getLinksInObject(function(allLinks) {
     // do what you need to do with allLinks here
});