我在使用AJAX的JavaScript中实现回调时遇到了一些问题。首先,脚本从文件中读取并放入变量:
jQuery.get('userdata/' + username + '.txt', function(data) {
var userid = data;
});
然后,该变量将在下面的函数中使用,该函数从.json文件中读取并选择only包含userid
中的值的结果。
function loadContacts(filter) {
var contacts = (function () {
var contacts = null;
$.ajax({
'url': 'userdata/' + username + '.json',
'dataType': "json",
'success': function (data) {
contacts = data;
contacts = contacts.filter(function(i) {
return i.id == userid;
});
}
});
return contacts;
})();
// some code for (filter) here
}
这里的问题是,在jQuery有时间创建userid
并从指定的文件中读取之前,loadContacts
函数已经在尝试从userid
中读取,因此它返回了一个未识别的变量错误。
在过去的2/3个小时里,我一直在努力学习如何在AJAX中实现回调,但在尝试了很多不同的变体后,我运气不佳。
我知道,通过实现回调,本质上我是在延迟loadContacts
函数,以等待jQuery.get
返回的成功消息,所以它在创建之前不会尝试查找userid
,我只是似乎无法让它工作。
有人能帮我吗?
我已经试着从重复的帖子中学习了,但我不明白吗?
由于AJAX请求是异步的,因此在接收到任何数据之前,您将从loadContacts()
函数返回一个值。您需要向函数传递一个回调函数,该函数可以在AJAX请求完成后执行。类似这样的东西:
function loadContacts(filter, callback) {
$.ajax({
url: 'userdata/' + username + '.json',
dataType: "json",
success: function (data) {
var contacts = data.filter(function(i) {
return i.id == userid;
});
callback && callback(contacts);
}
});
}
function doSomethingWithContacts(contacts) {
console.log(contacts);
}
loadContacts('foo', doSomethingWithContacts);
最简单的方法是从第一个get请求的结果中调用loadContacts函数。
var filter = function(){...};
var contacts = false;
jQuery.get('userdata/' + username + '.txt', function(data) {
var userid = data;
contacts = loadContacts(filter);
});
您还可以使用jQuery 的延迟函数
来一次承诺之旅吧
要异步获取数据,请同步这些调用并处理数据。
//creating a few "promises"
var pUserId = $.get('userdata/' + username + '.txt');
var pData = $.ajax({
'url': 'userdata/' + username + '.json',
'dataType': "json"
});
//filter pData by pUserId, as soon as both are available
var pUserdata = $.when(pUserId, pData).then(function(userId, data){
return data.filter(function(item){
return item.id === userId
})
});
//just log these three, as soon as they are available
$.when(pUserId, pData, pUserdata).done(function(userId, data, userdata){
console.log("userId:", userId);
console.log("data:", data);
console.log("userdata:", userdata);
});
这取决于你,你想如何将其封装到特定的函数中。
不要将过滤器与执行ajax调用的函数混合使用。因为每次需要这些数据的子集时,都必须进行ajax调用。将数据刷新和筛选分离。