2

私は以下の方法を持っています:

 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関数は、非同期 ajax リクエストの完了を待たないnullため、常に戻ります。getCities

この問題を解決するにはどうすればよいですか? (リクエストは非同期である必要があります)

4

4 に答える 4

3

これに対する最善の解決策は、Deferred オブジェクトを使用することです。AJAX 呼び出しを非同期にする必要があるため、将来のある時点でそのデータを返す というpromisegetCitiesを関数に返させる必要があります。

生データをキャッシュに保存する代わりに、これらの promise を保存します。

すでに解決済みの promise を要求すると、すぐに完了します。キャッシュされたオブジェクトに対する保留中の要求が既に存在する場合、非同期 AJAX 呼び出しが開始され、その promise を待機しているすべての未解決のコールバックが順番に開始されます。

これはもちろんテストされていませんが、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 };
            });
        });
    });
}

.pipeAJAX 応答を必要な形式に後処理するために を使用していることに注意してください。結果は別の遅延オブジェクトであり、実際には後者がキャッシュに格納されます。

使用法は次のようになります。

getCities().done(function(cities) {
    // use the cities array
});
于 2012-11-16T12:24:24.907 に答える
1

コールバックあり:

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
});
于 2012-11-16T11:29:29.843 に答える
1

データを非同期的にフェッチする関数から結果を返すことはできません。

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しないでください。これはひどい習慣であり、サーバーが応答するまでページをロックします。

于 2012-11-16T11:29:38.877 に答える
0

あなたは自分自身と矛盾しているようです。

定義上、非同期のものは、スクリプトを一時停止して実行の終了を待つことはありません。待機する場合は、非同期にすることはできません。

これを修正する最善の方法は、最終結果を別の関数に渡すコールバック関数を ajax 成功関数に追加することです。この関数は残りの実行を処理します。

于 2012-11-16T11:30:59.743 に答える