Javascript Javascript返回没有中断功能
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4774311/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Javascript return not breaking out of function
提问by RichJohnstone
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? 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.
请问我做错了什么?谢谢你。
回答by Pointy
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. 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). Then the main function can check the local variable to see if it was set.
您可以.each()
通过返回false
而不是来终止 的循环行为true
,但这仍然不会让您脱离外部函数。您可能应该考虑的是在外部函数中设置一个局部变量,并将内部函数设置为在找到某些内容时(然后中断.each()
循环)。然后主函数可以检查局部变量,看它是否被设置。
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.
在这种情况下,我真的很想使用 a.reduce()
或.inject()
API,但 jQuery 没有,而且他们真的反对。
回答by T.J. Crowder
Return false
, rather than true
, to terminate the each
loop; from the docs:
Return false
,而不是true
,终止each
循环;从文档:
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. You'll need to set a flag so you know whether you found something, e.g. something like this:
each
但是,这只会终止您的循环,而不是整个功能。你需要设置一个标志,这样你才能知道你是否找到了一些东西,例如这样的东西:
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
回答by Thai
$.get
is an asynchronous function, that means, the main function, artistExists
will return immediately, and a GET request will be initiated. To be able to get the result you will need a callback.
$.get
是一个异步函数,也就是说,main 函数artistExists
会立即返回,并且会发起 GET 请求。为了能够获得结果,您将需要回调。
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
});
回答by RichJohnstone
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. Then the following edit of my original failing function:
'ajax' 选项中的 'async: false' 对使调用同步。然后对我原来的失败函数进行以下编辑:
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. 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. Don't know why I couldn't think of doing this yesterday.
console.log 行将被删除。然而,它们表明,事情现在正在按照我想要的顺序发生。因此,如上所述,新的同步 .sget 函数和“找到”标志的使用已经为我完成了诀窍。不知道为什么我昨天没想到这样做。
Thanks everyone.
谢谢大家。