异步xhr和回调

时间:2016-08-13 10:39:09

标签: javascript jquery asynchronous jquery-callback

我在等待DOM元素存在时遇到问题。

首先,我在后端制作一个XHR并从那里获得一些信息:

mysqldump

这些功能在这里:

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

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

正如你所看到的,有一个回调是在1ms超时之后执行的(我之前在堆栈的某个地方发现了这个技巧),但是另一个函数不时会看到附加的元素。 我也试过

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();
}
到目前为止没有运气。

在这种情况下,有人可以建议如何正确地等待元素吗?

3 个答案:

答案 0 :(得分:1)

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

此代码将立即执行您的函数highlightAndSearchTags并且将发送结果值而不是您的回调,如果您想将其用作回调,则只需传递函数名称,如:

loadTags(15, highlightAndSearchTags);

如果您需要传递searchParamsearchStr参数,请将其添加为参数:

loadTags(15, highlightAndSearchTags, searchParam, searchStr);

加载代码后,您可以使用添加到searchParam功能的searchStrloadTags参数直接呼叫回调:

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();
}

另一种方法也可以是将回调包装在一个自执行的匿名函数中。这样可以防止highlightAndSearchTags立即执行,以便您以后可以在加载代码时调用它:

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

答案 1 :(得分:1)

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

由于已经提到过多个注释,你必须将它包装到一个函数中,这样当你调用loadTags函数时它就不会被调用

答案 2 :(得分:1)

您没有传递任何回调函数。您正在立即调用该函数并传递未定义的highlightAndSearchTags函数的返回值。

可以创建匿名函数并将其作为

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