[英]“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. 随着“结果”的记录被注销为未定义状态,您将能够在控制台中看到问题。
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. 立即返回计算得出的值就可以了。
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.