0

jQueryDeferredで少し問題が発生しています。

関数ラッパー内でjQueryajax呼び出しを使用しており、スコープ順に2つの成功コールバックを次々にチェーンしようとしています。ただし、両方の成功コールバックが同時に実行されているため、問題が発生しています。

私の最初の関数呼び出しは次のようになります(system.logはよりスマートなconsole.logです)。

serverpaths.setConfig(path).then(system.log("BAM! SERVERPATHS: " + serverpaths));

このsetConfigメソッド内に、.then()がチェーンされたAJAX呼び出しがあります。(system.deferはjQuery.Deferredオブジェクトを返すラッパーです。http.getはjQuery.ajaxのラッパーです。)

config.setConfig = function (configObj) {
    var that = this;
    var inlineHelper = function (data) {
        return system.defer(function (dfd) {
            for (var key in data) {
                system.log("Config[" + key + "]: " + that[key]);
                system.log("Data[" + key + "]: " + data[key]);
                that[key] = data[key];
                system.log("New Config[" + key + "]: " + that[key]);
            }
        }).promise();
    };

    if (typeof configObj === "string") {
        http.get("api/getPathConfig")             // The problem seems to be in this area
            .then(function (data) {
                return system.defer(function () {
                    inlineHelper(data);
                }).promise();
            });
    } else {
        return system.defer(function () {
            inlineHelper(configObj);
        }).promise();
    }
};

理想的には、ajaxリクエストを呼び出してから、inlinehelperを呼び出してから、system.logを呼び出す必要があります。これは、promiseオブジェクトをreturnステートメントでチェーンにバックアップしているためです。ここでの問題は、ajaxリクエストが呼び出され、system.logとinlinehelperが同時に呼び出されることです。

誰かが以前にこのような問題に遭遇したことがありますか?ここでは、関数スコープと非同期呼び出しが互いに競合しているようです。私はこれを理解できると確信していますが、それは完全に論理的ではないようです-私の推測では、ajaxリクエストが成功すると、メインスコープで.then()呼び出しがトリガーされます。私はこれを解決できると確信していますが、考えを跳ね返すための開発者の素晴らしいコミュニティを持つことは役に立ちます。

アドバイスありがとうございます。ありがとうございました!

4

1 に答える 1

0

.then(function() { return promise })もしません。返されたpromiseは、次の遅延コールバックに伝播されません。

これを行う場合は、.pipe()の代わりにを使用してください.then()。このようにして、約束を連鎖させることができます。

3つの非同期呼び出しをチェーンする場合は、次のようにします。

firstDeferredCall.pipe(secondDeferredCall).pipe(thirdDeferredCall)

あなたが書くなら

firstDeferredCall.then(secondDeferredCall).then(thirdDeferredCall)

thirdDeferredCallsecondDeferredCall呼び出しが実行されるのを待ちません。

編集: timが言ったように、jQuery1.8以降.pipeは非推奨になりました。

jQuery 1.8以降を使用している場合は、これを使用して、を.then置き換えることができます.pipe.thenのドキュメントを参照してください。この場合、コードは変更なしで適切であるはずです。

于 2012-06-14T11:52:59.930 に答える