[英]How to wait ajax callback result from another callback?
我有以下方法:
self.getOrAddCache = function (key, objectFactory) {
var data = self.getFromCache(key);
if (!data) {
data = objectFactory();
if (data && data != null)
self.addToCache(key, data);
}
return data;
};
我这样使用:
function getCities()
{
var cities = getOrAddCache(CacheKeys.Cities, function() {
var cityArray = new Array();
// get city informations from service
$.ajax({
type: "GET",
async: true,
url: "service/cities",
success: function (response) {
$.each(response, function(index, value) {
cityArray.push({
name: value.name,
id: value.id
});
});
}
});
if (cityArray.length > 0)
return cityArray;
else {
return null;
}
});
return cities;
}
getCities
函数始终返回null
因为getCities
不等待完成异步Ajax请求。
我该如何解决这个问题? (请求必须是异步的)
最好的解决方案是使用Deferred对象。 由于您需要异步进行AJAX调用,因此您应该让getCities
函数返回一个在将来某个时刻返回该数据的承诺 。
您可以存储这些承诺,而不是将原始数据存储在缓存中。
如果您请求已经解决的承诺,则将立即完成。 如果已经有对缓存对象的未决请求,则将启动异步AJAX调用,并且将依次启动所有等待该诺言的未完成回调。
这样的事情应该可以工作,尽管这当然未经测试,E&OE等,等等。
self.getCached = function(key, objectFactory) {
var def = self.getCache(key);
if (!def) {
def = objectFactory.call(self);
self.addToCache(key, def);
}
return def;
}
function getCities() {
return getCached(CacheKeys.Cities, function() {
return $.ajax({
type: 'GET',
url: 'service/cities'
}).pipe(function(response) {
return $.map(response, function(value) {
return { name: value.name, id: value.id };
});
});
});
}
请注意,使用.pipe
将AJAX响应后处理为所需的格式,结果是另一个延迟的对象,实际上是后者存储在缓存中。
现在的用法是:
getCities().done(function(cities) {
// use the cities array
});
带有回调:
function getCities(callbackFunction)
{
var cities = getOrAddCache(CacheKeys.Cities, function() {
var cityArray = new Array();
// get city informations from service
$.ajax({
type: "GET",
async: true,
url: "service/cities",
success: function (response) {
$.each(response, function(index, value) {
cityArray.push({
name: value.name,
id: value.id
});
});
callbackFunction(cityArray);
}
});
});
}
getCities(function(cityArray){
// do stuff
});
您不能从异步获取数据的函数中返回结果。
将您的getCities函数更改为一个接受回调的函数:
function fetchCities(callback) {
var cities = getOrAddCache(CacheKeys.Cities, function() {
var cityArray = new Array();
// get city informations from service
$.ajax({
type: "GET",
async: true,
url: "service/cities",
success: function (response) {
$.each(response, function(index, value) {
cityArray.push({
name: value.name,
id: value.id
});
});
if (callback) callback(cityArray);
}
});
});
}
并像这样使用它:
fetchCities(function(cities) {
// use the cities array
});
请注意,从技术上讲,使用async:true
可以使代码等待响应,但不要使用它:这是很糟糕的做法,它会锁定页面直到服务器应答为止。
你似乎在矛盾自己。
根据定义,异步的内容不会暂停脚本以等待脚本执行结束。 如果确实等待,则它不能是异步的。
解决此问题的最佳方法是在ajax成功函数中添加一个回调函数,该函数将最终结果传递给另一个处理其余执行的函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.