Javascript返回没有突破功能

时间:2011-01-23 14:29:08

标签: javascript jquery

我有一个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

我是否正确地认为'return true'行应该退出函数的执行?我以为会这样,但是在找到记录并运行第一个警报后,执行继续到底部的故障警报。

我做错了什么?谢谢。

4 个答案:

答案 0 :(得分:15)

是的,它确实“退出”了该功能的执行。问题是,“哪个功能?”在这种情况下,答案应该非常明确:它是传递给.each()的函数。

您可以通过返回.each()而不是false来终止true的循环行为,但这仍然不会让您退出外部函数。您应该考虑的是在外部函数中设置局部变量,并在找到内容时设置内部函数(然后打破.each()循环)。然后main函数可以检查局部变量以查看它是否已设置。

在这种情况下,我真的想使用.reduce().inject() API,但jQuery没有,并且他们真的反对它。

答案 1 :(得分:14)

返回false而不是true来终止each循环;来自the docs

  

我们可以通过返回false来停止回调函数中的循环。

这只会终止你的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

答案 2 :(得分:4)

$.get是一个异步函数,这意味着主函数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);

    });
}

然后使用,您需要使用回调函数。从

var isExists = artistExists('lol');
// do stuff

您需要将其更改为:

artistExists('lol', function(isExists) {
    // do stuff
});

答案 3 :(得分:1)

感谢您的所有建议。最后我决定需要一个同步调用,所以我创建了以下新版本的.get函数,名为.sget:

    jQuery.extend({
sget: function( url, callback, type ) {
        return jQuery.ajax({
            type:       "GET",
            url:        url,
            success:    callback,
            async:      false,
            dataType:   type
        });
    }
});

'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;

}

将删除console.log行。但他们表示,事情现在按照我想要的顺序发生。所以新的同步.sget函数和使用'found'标志,如上所述,已经为我做了诀窍。不知道为什么我昨天想不到这样做。

谢谢大家。