1

こんにちは、私はかなりの回数実行されるコードを持っています

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

アイデアは、任意のjsonファイルを渡すことができ、ローダーがそれを処理することです

ここに async false 形式のローダーがあります

  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;

しかし、これは async false 形式であり、jQuerymobile でより適切に動作させるには、これを async true 形式にする必要があるため、ここでいくつかの助けを借りて、非同期のポイントに到達することができました

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");
        });

これは asynloader を呼び出します

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;

問題は、これを機能させるために、this.cache[name]; を返すのではなく、$.ajax(parameters) を返す必要があることです。そうしないと、javascript エラーが発生します。問題は、maps.json を 2 回目にロードするときに $.ajax(parameters) を取得するように変更すると、this.cache からデータが取得されず、役に立たないjsonファイル

誰か助けてくれませんか

ありがとう :)

4

3 に答える 3

1

$.ajaxオブジェクトDeferred返します。あなたもあなた自身のDeferredオブジェクトを返すことができます。新しいコードは次のようになります。

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;
    }
}
于 2012-12-31T03:07:24.010 に答える
0

2つの提案:

  • this参照することは避けてくださいAsyncLoader

  • Object.hasOwnProperty()ではなく、オブジェクトプロパティの存在をテストしtypeof .... == 'undefined'ます。

JS:

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()は、少なくとも従来の意味では、データを返そうとはしません。代わりに、「約束」を返します。これは、必要なデータがキャッシュからすでに利用可能である場合はすぐに解決されるか、サーバーが応答したときに解決されます。

どちらの場合も、に渡された値は、 (またはまたは)メソッドで指定された関数の引数として呼び出されdfrd.resolve(...)たスコープ内で使用可能になり、返されたPromiseで呼び出されます(通常はメソッドチェーンによって)。AsyncLoader.load().done().always().then()

例えば ​​:

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を介してデータを受信するには、常に正しい方法で記述する必要があります。

于 2013-01-01T23:59:51.923 に答える
0

うーん、これはうまくいきません..

これを使えば

コレクション

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);

});

非同期ローダー

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 にする必要があります

ありがとう

于 2012-12-31T04:30:18.507 に答える