2016-08-13 10 views
0

DOM elemsが存在するのを待つことに問題があります。非同期xhrとコールバック

$(document).ready(function() { 
    var searchParam, searchStr; 
    // some values to vars 

    loadTags(15,highlightAndSearchTags(searchParam,searchStr)); 
}); 

機能はここにある:すべての

まず、私は私のバックエンドにXHRを作成し、そこからいくつかの情報を取得するあなたが見ることができるように

function highlightAndSearchTags(searchParam, searchStr) { 
    if (searchParam == 'tags') { 
     var selectedTags = searchStr.split(','); 
     console.log($("#my_favorite_latin_words").children().length); // sometimes returns 0, sometimes returns number of <span> in the div (see loadTags()) 
     for (var i = 0; i < selectedTags.length; i++) { 
      $("#" + selectedTags[i]).toggleClass("tag-selected"); 
     } 
    } 
} 

function loadTags(showedTagsLength, callback) { 
    var xhr = new XMLHttpRequest(); 
    xhr.open('GET', apiUrl + "tags/", true); 
    xhr.withCredentials = true; 
    xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); 
    xhr.onreadystatechange = function() { 
     if (xhr.readyState == 4) { 
      if (xhr.status != 200) { 
       console.log(xhr.responseText); 
      } 
      else { 
       tagList = JSON.parse(xhr.responseText); 
       tagList = tagList.results; 

       for (var i = 0; i < showedTagsLength; i++) { 
        $("#my_favorite_latin_words").append("<span id=\'" + tagList[i].tag_pk + "\'>" + tagList[i].name + "</span>"); 
       } 

      } 
      setTimeout(callback, 1); //found this trick somewhere on stackoverflow 
     } 
    }; 
    xhr.send(); 
} 

がコールバックが存在します1msのタイムアウト後に実行されます(私はこのトリックを少し前にスタックのどこかに見つけました)が、別の関数は時折追加された要素を見ません。 私はまた、これまで運と

callback.call() 

を試してみました。

この場合、要素を正しく待機する方法は誰にでも分かりますか?

+0

'loadTags(15、highlightAndSearchTags(searchParam、searchStr))として作成し、渡すことができ、' - >これは '直ちに' highlightAndSearchTags(searchParam、searchStr)を呼び出しと戻りを通過'callback'として' loadTags'に値( 'undefined')を設定します。 – Andreas

+0

setTimeout" trick "は不要です - あなたの問題は@Andreasが指摘しているように...' loadTags(15、function(){highlightAndSearchTags(searchParam 、searchStr);}); '代わりに –

答えて

1
loadTags(15,function(searchParam,searchStr){highlightAndSearchTags(searchParam,searchStr)}); 

を、あなたはそれが呼ばイマイチように関数にそれをラップする必要があります。これは、あなたのタグがロードされたときに、後でそれを呼び出すことができますので、すぐに実行されるようにhighlightAndSearchTagsを防ぐことができますloadTags関数を呼び出すとき

1
loadTags(15,highlightAndSearchTags(searchParam,searchStr)); 

このコードは、すぐに機能highlightAndSearchTagsを実行し、結果の値は、あなたがコールバックとしてそれを使用したい場合は、あなただけのような関数名を渡す必要があり、コールバックの代わりに送信されます。

loadTags(15, highlightAndSearchTags); 

あなたは、あなたのsearchParamsearchStrパラメータを渡すパラメータとしてそれらを追加する必要がある場合:あなたのタグがロードされるとき

loadTags(15, highlightAndSearchTags, searchParam, searchStr); 

、あなたが直接あなたのloadTags機能に追加searchParamsearchStrパラメータを使用してコールバックを呼び出すことができます。

function loadTags(showedTagsLength, callback, searchParam, searchStr) { 
    var xhr = new XMLHttpRequest(); 
    xhr.open('GET', apiUrl + "tags/", true); 
    xhr.withCredentials = true; 
    xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); 
    xhr.onreadystatechange = function() { 
     if (xhr.readyState == 4) { 
      if (xhr.status != 200) { 
       console.log(xhr.responseText); 
      } 
      else { 
       tagList = JSON.parse(xhr.responseText); 
       tagList = tagList.results; 

       for (var i = 0; i < showedTagsLength; i++) { 
        $("#my_favorite_latin_words").append("<span id=\'" + tagList[i].tag_pk + "\'>" + tagList[i].name + "</span>"); 
       } 

      } 

      callback(searchParam,searchStr); 
     } 
    }; 
    xhr.send(); 
} 

別のアプローチは、自己実行匿名関数でコールバックをラップすることができます。すでに述べたように、複数のコメントとして

loadTags(15, function() { highlightAndSearchTags(searchParam, searchStr); }); 
+0

コールバックを実行する関数にパラメータとしてコールバックのパラメータを追加するのはなぜですか? O.o – Andreas

+0

私は2つのアプローチをパラメータとして追加するか、コールバックを自己実行型の無名関数にラップする方法を説明しました。 – HiDeo

+0

ありがとう@HiDeo! –

1

コールバック関数を渡していません。すぐに関数を呼び出し、未定義の関数highlightAndSearchTagsの戻り値を渡します。

匿名関数は

loadTags(15,function(){ 
     highlightAndSearchTags(searchParam,searchStr) 
    }); 
関連する問題