异步 xhr 和回调
Async xhr and callback
我在等待 DOM 个元素存在时遇到问题。
首先,我在后端创建了一个 XHR,并从那里获取了一些信息:
$(document).ready(function() {
var searchParam, searchStr;
// some values to vars
loadTags(15,highlightAndSearchTags(searchParam,searchStr));
});
函数在这里:
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 Whosebug
}
};
xhr.send();
}
如您所见,有一个回调在 1 毫秒超时后执行(我刚才在堆栈的某个地方发现了这个技巧),但是另一个函数有时看不到附加的元素。
我也试过
callback.call()
到目前为止运气不好。
有人可以建议在这种情况下如何正确等待元素吗?
loadTags(15,highlightAndSearchTags(searchParam,searchStr));
此代码将立即执行您的函数 highlightAndSearchTags
并且将发送结果值而不是您的回调,如果您想将其用作回调,您只需传递函数名称,例如:
loadTags(15, highlightAndSearchTags);
如果您需要传递 searchParam
和 searchStr
参数,请将它们添加为参数:
loadTags(15, highlightAndSearchTags, searchParam, searchStr);
加载标签后,您可以使用添加到 loadTags
函数的 searchParam
和 searchStr
参数直接调用回调:
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); });
loadTags(15,function(searchParam,searchStr){highlightAndSearchTags(searchParam,searchStr)});
正如已经提到的多个评论,您必须将其包装到一个函数中,以便在调用 loadTags 函数时不会调用它
您没有传递任何回调函数。您将立即调用该函数并传递未定义的 highlightAndSearchTags
函数的返回值。
可以创建匿名函数并将其传递为
loadTags(15,function(){
highlightAndSearchTags(searchParam,searchStr)
});
我在等待 DOM 个元素存在时遇到问题。
首先,我在后端创建了一个 XHR,并从那里获取了一些信息:
$(document).ready(function() {
var searchParam, searchStr;
// some values to vars
loadTags(15,highlightAndSearchTags(searchParam,searchStr));
});
函数在这里:
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 Whosebug
}
};
xhr.send();
}
如您所见,有一个回调在 1 毫秒超时后执行(我刚才在堆栈的某个地方发现了这个技巧),但是另一个函数有时看不到附加的元素。 我也试过
callback.call()
到目前为止运气不好。
有人可以建议在这种情况下如何正确等待元素吗?
loadTags(15,highlightAndSearchTags(searchParam,searchStr));
此代码将立即执行您的函数 highlightAndSearchTags
并且将发送结果值而不是您的回调,如果您想将其用作回调,您只需传递函数名称,例如:
loadTags(15, highlightAndSearchTags);
如果您需要传递 searchParam
和 searchStr
参数,请将它们添加为参数:
loadTags(15, highlightAndSearchTags, searchParam, searchStr);
加载标签后,您可以使用添加到 loadTags
函数的 searchParam
和 searchStr
参数直接调用回调:
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); });
loadTags(15,function(searchParam,searchStr){highlightAndSearchTags(searchParam,searchStr)});
正如已经提到的多个评论,您必须将其包装到一个函数中,以便在调用 loadTags 函数时不会调用它
您没有传递任何回调函数。您将立即调用该函数并传递未定义的 highlightAndSearchTags
函数的返回值。
可以创建匿名函数并将其传递为
loadTags(15,function(){
highlightAndSearchTags(searchParam,searchStr)
});