简体   繁体   English

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

[英]“Return” from function not getting assigned to variable

I have written a function that searches recursively through an object to get all specific elements out of it, and return the resulting array of elements. 我编写了一个函数,该函数以递归方式搜索对象,以从中获取所有特定元素,然后返回结果元素数组。

The function itself works perfectly, but for some reason the result of the "return" portion does not get assigned to the variable that called the function. 该函数本身可以完美地工作,但是由于某种原因,“返回”部分的结果未分配给调用该函数的变量。

This is the function itself: 这是函数本身:

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);
};

This is a test object to run it against that matches the structure of the actual 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: [
                        {

                        }
                    ]
                }
            ]
        }
    ]
}

And this is a fiddle that duplicates the problem. 这是一个重复出现问题的小提琴。 You'll be able to see the problem in the console as the logging of "result" gets logged out as undefined. 随着“结果”的记录被注销为未定义状态,您将能够在控制台中看到问题。

http://jsfiddle.net/KS7LG/ http://jsfiddle.net/KS7LG/

The function you assign to getLinksInObject doesn't have a return statement. 您分配给getLinksInObject函数没有return语句。 It will always return undefined . 它将始终返回undefined

The only return statement in your entire code is this: 整个代码中唯一的return语句是这样的:

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

That function is being called by setTimeout , and setTimeout doesn't pay attention to any return values from the functions it calls. 该函数由setTimeout调用,而setTimeout并不关注它调用的函数的任何返回值。

setTimeout is asynchronous, it runs code later and doesn't block the function that called it from continuing. setTimeout是异步的,它稍后运行代码,并且不会阻止调用它的函数继续。 If you want to deal with data generated after the time runs out, then you have to do so going forwards from the function you pass, it is too late to pass data back. 如果要处理时间用完后生成的数据,则必须从传递的函数开始处理,现在将数据传递回已为时已晚。

Javascript (mostly) operates synchronously so you don't need any timeout related code to make your function work. Javascript(大多数情况下)是同步运行的,因此您不需要任何与timeout相关的代码即可使function正常工作。 Returning the value immediately as it is calculated will do fine. 立即返回计算得出的值就可以了。

See: jsFiddle 参见: jsFiddle

In particular, the following change: 特别是以下更改:

              //resetTimeout(); <- remove this

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

//removed timeout code

getLinks(object);
return allLinks;

Return won't work with setTimeout as it's asynchronous. Return与setTimeout不兼容,因为它是异步的。 You'll need to create a callback to achieve what you want: 您需要创建一个回调来实现所需的功能:

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

   // ...
};

Then you'll have to modify the getLinksInObject call: 然后,您必须修改getLinksInObject调用:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM