繁体   English   中英

如何等待另一个回调的ajax回调结果?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM