2011-01-23 14 views
12

を抜け出していない返す私はアーティストがXMLファイルに存在するかどうかを確認javascript関数を持っている: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

trueではなく、falseを返して、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'はその反復**と** stop loopingのコールバックから飛び出します。 –

14

はい、機能の実行を「終了」します。問題は「どの機能?」この場合の答えはかなり明白です:それは.each()に渡された関数です。

.each()のループ動作を終了させるには、trueではなくfalseを返すことができますが、依然として外部機能を引き出すことはできません。おそらく考慮する必要があるのは、外部関数にローカル変数を設定し、何かを見つけたときに内部関数を設定してから(.each()ループを壊す)ことです。次に、メイン関数は、ローカル変数が設定されているかどうかを調べることができます。

私は実際に.reduce()または.inject() APIを使用したいと考えていますが、jQueryにはこれがなく、実際には反対しています。

+0

ありがとうPointy、それは動作しますが、それは少しclunkyそうではありません。 break文の後に数値を入れることができれば素晴らしいだろう。 – 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); 

    }); 
} 

次に使用するには、コールバック関数を使用する必要があります。すべてのアドバイスを

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

このタイの反省のおかげで、これは明らかに行く方法です。私はちょうど私のコードでそれを使用する方法を理解していない、私は新しく、私は前にコールバックを使用したことがない。私は "if(artistExists($# 'artistfield'))){{do do}}"のようなコード行を作りたいと思っていました。コールバックビジネスでどうすればいいですか?どうもありがとう。 – RichJohnstone

+0

非同期関数とは、呼び出したときに即座に結果を得ることができない関数を意味します。コールバック関数は、結果が利用可能になったときに通知を受けるために重要です。見てみると、 'artistExists'関数は別の引数' cb'を受け取り、 'cb'が' cb(found) 'に結果を得た後に' cb'が呼び出されます。 – Thai

+0

もう一度タイに感謝します。私は、リクエストの非同期性が結果を待たなければならないことを意味します。私が明確にしていないのは、自分のcb /コールバック関数を使って、元の呼び出し元のコード行にtrue/falseを戻す方法です。ここで少しのコードで私を助けることができたら、本当に感謝しています。再度、感謝します。 – RichJohnstone

1

ありがとう:

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

から、あなたはそれを変更する必要があります。最後に、私は、私は同期呼び出しを必要と決めたので、私は.sgetと呼ばれるに.get機能の次の新しいバージョンを、作っ:

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関数と 'found'フラグの使用は、私のためのトリックを行っています。なぜ私はこれを昨日やっていると思うことができなかったのか分かりません。

ありがとうございました。