[英]Javascript return not breaking out of function
I have a javascript function which checks to see if an artist exists in an XML file: 我有一个javascript函数,它检查XML文件中是否存在艺术家:
function artistExists(artist) {
// get data from artists.xml
$('.loading').show();
$.get(artists_xml, function(xml){
$('.loading').hide();
$(xml).find('artist').each(function(){
if ($(this).find("ar_artist").text() == artist.val()) {
alert ('artist exists');
return true;
} //end if
}); // end each
alert ('artist does not exist');
return false;
}); // end .get function
} // end of artistExists function
Am I right in thinking that the 'return true' line should quit execution of the function? 我是否正确地认为'return true'行应该退出函数的执行? I thought it would, but after finding a record and running the first alert execution continues to the failure alert at the bottom.
我以为会这样,但是在找到记录并运行第一个警报后,执行继续到底部的故障警报。
What am I doing wrong please? 我做错了什么? Thank you.
谢谢。
Return false
, rather than true
, to terminate the each
loop; 返回
false
而不是true
,以终止each
循环; from the docs : 来自文档 :
We can stop the loop from within the callback function by returning
false
.我们可以通过返回
false
来停止回调函数中的循环。
That will just terminate your each
loop, though, not the overall function. 那将只是终止你的
each
循环,而不是整个功能。 You'll need to set a flag so you know whether you found something, eg something like this: 你需要设置一个标志,以便你知道你是否找到了一些东西,例如:
function artistExists(artist) {
// get data from artists.xml
$('.loading').show();
$.get(artists_xml, function(xml){
var found = false; // <== Added
$('.loading').hide();
$(xml).find('artist').each(function(){
if ($(this).find("ar_artist").text() == artist.val()) {
alert ('artist exists');
found = true; // <== Added
return false; // <== Modified
} //end if
}); // end each
if (!found) { // <== Added
alert ('artist does not exist');
} // <== Added
return found; // <== Modified
}); // end .get function
} // end of artistExists function
Yes, it does "quit" execution of the function. 是的,它确实“退出”了该功能的执行。 The question is, "which function?"
问题是,“哪个功能?” In this case the answer should be pretty clear: it's the function passed to
.each()
. 在这种情况下,答案应该非常明确:它是传递给
.each()
的函数。
You can terminate the looping behavior of .each()
by returning false
instead of true
, but that still won't get you out of the outer function. 您可以通过返回
false
而不是true
来终止.each()
的循环行为,但这仍然不会让您退出外部函数。 What you should probably consider is to set up a local variable in the outer function, and have the inner function set that when it finds something (and then break the .each()
loop). 您应该考虑的是在外部函数中设置局部变量,并在找到内容时设置内部函数(然后打破
.each()
循环)。 Then the main function can check the local variable to see if it was set. 然后main函数可以检查局部变量以查看它是否已设置。
This is a case where I'd really like to use a .reduce()
or .inject()
API, but jQuery doesn't have one and they're really opposed to it. 这是我真的很喜欢用的情况
.reduce()
或.inject()
API,但jQuery的没有一个和他们真的反对。
$.get
is an asynchronous function, that means, the main function, artistExists
will return immediately, and a GET request will be initiated. $.get
是一个异步函数,这意味着,主函数artistExists
将立即返回,并且将启动一个GET请求。 To be able to get the result you will need a callback. 为了能够得到结果,您需要回调。
function artistExists(artist, cb) {
$('.loading').show();
$.get(artists_xml, function(xml) {
var found = false;
$('.loading').hide();
$(xml).find('artist').each(function(){
if ($(this).find("ar_artist").text() == artist.val()) {
found = true;
return false; // use return false to stop .each()
}
});
// the built in action.
if (found) {
alert ('artist exists');
} else {
alert ('artist does not exist');
}
// call the callback function
cb (found);
});
}
Then to use, you need to use a callback function. 然后使用,您需要使用回调函数。 From
从
var isExists = artistExists('lol');
// do stuff
You need to change it to: 您需要将其更改为:
artistExists('lol', function(isExists) {
// do stuff
});
Thanks for all the advice. 感谢所有的建议。 In the end I decided I needed a synchronous call, so I made the following new version of the .get function, called .sget:
最后我决定需要一个同步调用,所以我创建了以下新版本的.get函数,名为.sget:
jQuery.extend({
sget: function( url, callback, type ) {
return jQuery.ajax({
type: "GET",
url: url,
success: callback,
async: false,
dataType: type
});
}
});
The 'async: false' pair in the 'ajax' options makes the call synchronous. 'ajax'选项中的'async:false'对使调用同步。 Then the following edit of my original failing function:
然后编辑我原来的失败函数:
function artistExists(artistname) {
var found = false;
console.log("From Input:Artist= " + artistname.val());
// get data from artists.xml
$('.loading').show();
$.sget(artists_xml, function(xml){ // new synchronous get
$('.loading').hide();
$(xml).find('artist').each(function(){
if ($(this).find("ar_artist").text() == artistname.val()) {
console.log('From File:Artist= ' + $(this).find("ar_artist").text());
found = true;
console.log("In each loop:Flag= " + found);
return;
} //end if
}); // end each
}); // end .get function
console.log("At end:Flag= " + found);
return found;
} }
The console.log lines will be removed. console.log行将被删除。 They show though, that things are now happening in the order I want.
但他们表示,事情现在按照我想要的顺序发生。 SO the new synchronous .sget function and the use of a 'found' flag, as advised above, have done the trick for me.
所以新的同步.sget函数和使用'found'标志,如上所述,已经为我做了诀窍。 Don't know why I couldn't think of doing this yesterday.
不知道为什么我昨天想不到这样做。
Thanks everyone. 感谢大家。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.