2011-01-23 80 views
12

我有一個JavaScript函數,它檢查是否在一個XML文件中存在的藝術家:的Javascript返回未打破的功能

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 

我是正確的思維是,「返回true」行應該退出執行的功能?我認爲它會,但是在找到一條記錄並運行第一個警報執行後,繼續執行底部的故障警報。

我在做什麼錯誤?謝謝。

回答

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 
+0

這已經很長時間了,但我有一個問題:我試圖只使用'return',它停止了'.each',所以'return false'不是必須做的或者是否有某種東西我應該知道? –

+1

@CagatayUlubay:只要'return'不會停止'each'循環,它只是跳出那個迭代的回調;循環將繼續進行下一次迭代。 'return false'將跳出該迭代的回調**和**停止循環。 –

14

是的,它會「退出」執行該功能。問題是,「哪個功能?」在這種情況下,答案應該很清楚:這是傳遞給.each()的函數。

您可以通過返回false而不是true來終止.each()的循環行爲,但仍不會讓您脫離外部函數。你應該考慮的是在外部函數中設置一個局部變量,並設置內部函數,當它找到某些東西(然後打破.each()循環)。然後主函數可以檢查局部變量是否被設置。

這是一個我真的很喜歡用.reduce().inject() API的例子,但jQuery沒有它,他們真的反對它。

+0

謝謝Pointy,它的工作,雖然它確實有點笨重不是。如果可以在休息後聲明數字,那將會很棒。 – RichJohnstone

+0

那麼問題是,當你的函數是JavaScript中的第一類值時,代碼的「靜態」安排實際上並沒有告訴你有關如何/何時/何地實際調用函數。 – Pointy

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 
}); 
+0

感謝這個泰國人 - 在反思中,這顯然是要走的路。我只是不太明白如何在代碼中使用它,我是新的,我從來沒有使用過回調。我希望能夠有一行代碼,如「if(artistExists($('#artistfield'))){// do stuff}」。我會怎麼跟這個回調業務談談呢?非常感謝。 – RichJohnstone

+0

異步功能意味着你打電話時無法立即得到結果的功能。回調函數非常重要,以便在結果可用時通知您。如果你看一下,'artistExists'函數接受另一個參數'cb','cb(found)'後面的結果會調用'cb'。 – Thai

+0

再次感謝泰國。我明白請求的異步性意味着我必須等待結果。我不清楚的是我如何使用我的cb /回調函數將true/false傳回給我的原始代碼行。如果你能在這裏幫助我一些代碼,我會很感激。再次感謝。 – RichJohnstone

1

感謝所有的建議。最後,我決定我需要一個同步調用,所以我做了不用彷徨功能的以下新版本,叫做.sget:

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

的「異步:假」對在「AJAX」選項使呼叫同步。然後我的原始失敗的功​​能如下編輯:

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函數和'找到'標誌的使用爲我完成了訣竅。不知道爲什麼我不能想到昨天這樣做。

謝謝大家。