web-dev-qa-db-ja.com

jqueryのとき/その後(またいつ/完了)が待機していない

この構文を使用する多くのサンプルを見てきましたが、何が問題なのかわかりません。「then」関数は、ajax呼び出しが戻る前に実行されています。

$ .deferredと他のいくつかのパターンも使用してみましたが、役に立ちませんでした。

誰かが私が欠けているものを見ることができますか?

私はデバッグしていて、ajax呼び出しが成功(またはエラー)データを返す前に、done/thenの内部から行われている呼び出しを確認できます。

助けてくれてありがとう。

メインコール:

this.addFirstTask = function(task) {
    var totalHours = GetHours();
    $.when(totalHours).done(function (data) {
        task.TaskHours(data);
        self.add(task);
    });
};

次のajax関数を呼び出しています。

function GetHours() {
    $.ajax({
        url: "/api/tst/GetMyData",
        type: 'GET',
        dataType: 'json',

        success: function(data) {
           return data;
        },

        error: function(data) {
            return 0;
        }
    });
};

ありがとう!

検死:

追加のアドバイスに従って、ajax呼び出しにリターンを追加することに加えて、ajax呼び出しから成功とエラーを削除し、addFirstTaskを次のように変更しました。

this.addFirstTask = function(task) {
    var totalHours = GetHours();
    $.when(totalHours)
     .then(function (data) {task.TaskHours(data);})
     .done(function () { self.add(task); });
};

GetHoursが成功した場合、TaskHours値を更新します。失敗した場合はスキップします。 DONEは.NETのtry/catchの「FINALLY」のようなものであることに気付きました。したがって、すぐにタスクを追加し、値が戻ったときに監視可能なバインディングでタスクを更新させるのではなく、self.addも非同期呼び出しの一部です。

16
Julie Lerman
function GetHours() {
    return $.ajax({
        ...
    });
};

$ .ajax()はPromiseを返します。 $ .when()はPromiseのコレクションを受け取り、すべての入力Promiseが完了したときに完了するPromiseを返します。 promiseが正常に解決されたときの関数arg。

そのため、GetHoursはwhen()がラップできるというPromiseを返す必要があり、then()を呼び出します。実際にはwhen()の部分をスキップして、GetHoursからの戻り時に.thenを呼び出すだけです。

.when()も古いオブジェクトを取得するため、エラーは発生しません。また、Promiseインターフェースを実装していない場合は、すでに完了したPromiseのように扱われます。

28
Andy Smith

これはOPの問題ではありませんが、同様のことが起こりました。これは、promiseの配列を渡すことによって$ .when(...)を誤って呼び出していたためです。

jQuery.when のドキュメントに従って、複数のDeferredオブジェクトを待つ場合は、次のように呼び出す必要があります。

$.when( d1, d2 ).then(....);

つまり、配列内に複数の遅延オブジェクトがある場合はapply(...)を使用する必要があります。そうしないと、$。whenが正しく機能しません。したがって、遅延オブジェクトの配列の呼び出しは次のようになります。

$.when.apply(this, arrayOfDeferred).then(....);

これはJS Fiddleを示しています:

https://jsfiddle.net/Lvo4hrez/11/

8
kroolk

次のように、GetHours関数から$ .ajaxの結果を返す必要があります。

function GetHours() {
$.ajax({
    url: "/api/tst/GetMyData",
    type: 'GET',
    dataType: 'json',

    success: function(data) {
       return data;
    },

    error: function(data) {
        return 0;
    }
});

};

0
Adam