简体   繁体   English

Javascript返回没有突破功能

[英]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.

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