首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从async false移动到async true

从async false移动到async true
EN

Stack Overflow用户
提问于 2012-12-31 10:38:29
回答 3查看 990关注 0票数 1

嗨,我有一段代码,它运行了好几次

Loader.load('data/map.json')

我的想法是,我可以传入任何json文件,加载器将处理它。

下面是async false格式的加载器

代码语言:javascript
复制
  var Loader = {
    basePath: '',
    cache: {},
    load: function(name) {
        if(typeof this.cache[name] == 'undefined') {
            var loadUrl = (this.basePath == '') ? name : this.basePath + '/' + name;
            var parameters = {

                url: loadUrl,
                dataType: 'json',
                async: false,
                context: this,
                success: function(data) {
                    this.cache[name] = data;
                }
            };

            $.ajax(parameters);
        }
        return this.cache[name];
   }
};
return Loader;

但这是异步假格式,我需要将它转换为异步真格式,以便更好地与jQuerymobile一起工作,因此在这里提供了一些帮助,我设法使其达到异步的程度

代码语言:javascript
复制
var data = AsyncLoader.load('data/map.json').done(function(data, textStatus, jqXHR) {
            console.log("complete");

        }).fail(function(jqXHR, textStatus, errorThrown) {

            console.log("an error has occurred");

        }).always(function(jqXHR, textStatus) {
            console.log("running");
        });

这将调用异步加载器

代码语言:javascript
复制
function($) {
var AsyncLoader = {
    basePath: '',
    cache: {},
    load: function(name) {
        if(typeof this.cache[name] == 'undefined') {
            var loadUrl = (this.basePath == '') ? name : this.basePath + '/' + name;
            var parameters = {
                beforeSend: function() { $.mobile.showPageLoadingMsg(); },
                complete: function() {$.mobile.hidePageLoadingMsg(); },
                url: loadUrl,
                dataType: 'json',
                async: true,
                context: this,
                success: function(data) {
                    this.cache[name] = data;
                }
            };

            $.ajax(parameters);
        }

        return this.cache[name];
    }
};

return AsyncLoader;

问题是要使这项工作正常工作,我需要返回$.ajax(参数)而不是返回this.cachename;否则我会得到一个javascript错误。问题是,如果我将其更改为获取$.ajax(参数),当我第二次加载maps.json时,它不会从this.cache中获取数据,它将再次加载json文件,这是无用的

有人能帮上忙吗

谢谢:)

EN

回答 3

Stack Overflow用户

发布于 2012-12-31 11:07:24

$.ajax返回a Deferred object。您也可以返回自己的Deferred对象。您的新代码可能看起来有点像这样:

代码语言:javascript
复制
load: function(name) {
    // Is the object already in the cache?
    if(Object.prototype.hasOwnProperty.call(this.cache, name)) {
        // Yes! Return a Deferred that's already been resolved.
        return jQuery.Deferred().resolve(this.cache[name]);
    }else{
        // No! We have to load it. Let's still use our own Deferred, though:
        var deferred = jQuery.Deferred();

        // There's our Deferred. Now let's load it.
        jQuery.ajax({
            // ...
        }).done(function(data) {
            // We loaded it successfully!
            // Add it to our cache and resolve the Deferred.
            this.cache[name] = data;
            deferred.resolve(data);
        }).fail(function() {
            // Fail! Pass the failure on to our deferred.
            deferred.reject.apply(deferred, arguments);
        });

        // We've started the AJAX request. Now return our Deferred.
        return deferred;
    }
}
票数 1
EN

Stack Overflow用户

发布于 2012-12-31 12:30:19

嗯,这不是很有效..

如果我用这个

集合

代码语言:javascript
复制
var data = AsyncLoader.load('data/map.json').done(function(data) {

    var models = [];
    $.each(data.data.locations, function() {
        // RESERVED WORDS YO
        if(this['delete'] == 1) {
            return;
        }

        models.push(new MapLocationModel(this));

    });
    $t.reset(models);

});

异步加载器

代码语言:javascript
复制
function($) {
var AsyncLoader = {
    basePath: '',
    cache: {},
    load: function(name) {
        if(typeof this.cache[name] == 'undefined') {

            console.log("not cached");

            var deferred = jQuery.Deferred();
            var loadUrl = (this.basePath == '') ? name : this.basePath + '/' + name;
            var parameters = {
                beforeSend: function() { console.log("d"); },
                url: loadUrl,
                dataType: 'json',
                async: true,
                context: this,
                success: function(data) {
                    this.cache[name] = data;
                    deferred.resolve(data);
                }
            };

            $.ajax(parameters);
            return deferred;


        } else {

        console.log("cached");

        return jQuery.Deferred().resolve(this.cache[name]);

        }

    }
};

return AsyncLoader;

我将多次加载地图数据,并且永远不会从缓存中获取它。

但是,如果我在上面更改为async false,则可以正常工作,但我需要async为true

谢谢

票数 0
EN

Stack Overflow用户

发布于 2013-01-02 07:59:52

两个建议:

JS:

代码语言:javascript
复制
function($) {
    var AsyncLoader = {
        basePath: '',
        cache: {},
        load: function(name) {
            var dfrd = $.Deferred();
            if(!AsyncLoader.cache.hasOwnProperty(name)) {
                var loadUrl = (AsyncLoader.basePath == '') ? name : AsyncLoader.basePath + '/' + name;
                $.ajax({
                    beforeSend: function() { console.log("d"); },
                    url: loadUrl,
                    dataType: 'json',
                    async: true,
                    success: function(data) {
                        AsyncLoader.cache[name] = data;
                        dfrd.resolve(data);
                    }
                });
            }
            else {
                return dfrd.resolve(AsyncLoader.cache[name]);
            }
            return dfrd.promise();
        }
    };
    return AsyncLoader;
...
}(jQuery);

笔记

虽然AsyncLoader.load()可以在数据已经缓存时直接返回数据,但当数据需要从服务器获取时就不是这样了;原因是服务器响应是异步的。所需要的是一种机制,通过该机制,任何调用AsyncLoader.load()的表达式都可以以完全相同的方式接收数据,而不管AsyncLoader.load()是从缓存还是从服务器获取数据。

因此,在上面的代码中,AsyncLoader.load()并不试图返回数据,至少在传统意义上不是这样;相反,它返回一个"promise",如果所需的数据已经从缓存中可用,则立即解析,或者稍后当服务器响应时解析。

在这两种情况下,传递给dfrd.resolve(...)的值在调用AsyncLoader.load()的范围内变得可用,作为.done() (或.always().then())方法中指定的函数的参数,在返回的promise上调用(通常通过方法链接)。

例如:

代码语言:javascript
复制
AsyncLoader.load('myName').done(function(data) {
    console.log(data);
    //do wheatever else is necessary with `data` here.
});

这样,目标就达到了。通过返回promise (在AsyncLoader.load()中创建),所需的数据将以完全相同的方式在AsyncLoader.load()作用域之外可用,无论这些数据是从缓存中提取的还是从服务器新接收的。

调用AsyncLoader.load()的表达式完全不知道数据是否来自缓存,但必须始终以正确的方式写入才能通过返回的promise接收数据。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14096848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档