web-dev-qa-db-ja.com

jQuery Deferred:完了フィルター内からのPromiseの拒否

Fyi、jQueryの約束を学び始めたばかりなので、ここで少し混乱するかもしれません。

とにかく、応答の内容に基づいて、完了したフィルター内から拒否したいAJAXリクエストがあります:

return doAJAXRequest().then(function (data) {
    if (data.responseText == "YES") {
        return doOtherAJAXRequest();
    } else {
        this.reject(data);
    }
});

それは私が期待したようには機能しませんでした:

Uncaught TypeError: Object #<Object> has no method 'reject'

その応答に基づいてこの約束を失敗させるにはどうすればよいですか?それは可能ですか?それとも、ここで何をする必要があるのか​​混乱していますか?

24
Ajedi32

JQueryでは(他のいくつかのライブラリとは異なり)、promiseを「解決済み」状態から「拒否済み」状態に変換することは少し冗長であり、新しいDeferredの明示的な作成と拒否が必要です。

_function foo() {
    return doAJAXRequest().then(function (data, textStatus, jqXHR) {
        if (data.responseText == "YES") {
            return doOtherAJAXRequest(data);
        } else {
            return $.Deferred().reject(jqXHR, data, 'Not YES').promise();
        }
    });
)
_

ここで、_data.responseText !== "YES"_が失敗したajaxリクエストを(部分的に)模倣し、dataを渡すことができる場合、promiseが返されます。これは(おそらく)ダウンストリームの.fail()ハンドラーにとって重要です。このハンドラーは、errorThrownを読み取るまでどちらが発生したかを知らずに、本物のajax失敗と変換された成功条件の両方を処理する必要があります。

_foo().fail(function(jqXHR, textStatus, errorThrown) {
    if(errorThrown == 'Not YES') {
        //transmogrified success
        var data = textStatus;
        ...
    }
    else {
        //genuine ajax failure
        ...
    }
}); 
_

一般に、jqXHRオブジェクトから再取得するよりも、この方法でdataを渡す方が簡単です。これは、JSONでエンコードされたデータに特に当てはまります。そうでない場合は、フェイルハンドラーでもう一度デコードする必要があります。

35