48

promise を返す非同期関数が多数ある既存のプロジェクトがあります。場合によっては非同期関数が同期的に完了し、可能であればこのコードをより短く/より良くしたいと思うように、いくつかのキャッシュを追加しています:

        return $.Deferred(function(def) { def.resolve(); }).promise();

たとえば、次のようなほとんどの AJAX 要求を処理する Data Service クラスがあります。

function DataService() {

    var self = this;

    self.makeRequest = function(functionName, data) {
        return $.Deferred(function(def) {

            var jsonData = JSON.stringify(data);

            $.ajax({
                type: "POST",
                url: "WebService.asmx/" + functionName,
                data: jsonData,
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                error: function(xhr, status, error) {
                    var ex;
                    try {
                        ex = eval("(" + xhr.responseText + ")");
                        ex.message = ex.Message;
                        ex.Message = undefined;
                    } catch (ex2) {
                        ex = { message: "Invalid Response From Server:\r\n" + xhr.responseText };
                    }
                    if (ex.message == "LoginRequired") {
                        app.viewModels.main.loginRequired(true);
                    }
                    else {
                        app.showError(ex.message);
                    }
                    def.reject(ex.message);
                }
            });
        }).promise();
    }
}

次に、現在常に makeRequest を呼び出す別のクラスに関数があります。

self.deleteMe = function()
{
   return app.dataservice.makeRequest('deleteItem');
}

deleteMe 関数を更新して、常に makeRequest を呼び出すのではなく、代わりにいくつかの同期作業を行ってから戻るようにしたいと考えています。ただし、呼び出されたものは何でもそれを期待しているため、プロミスを返す必要がありますが、「すでに完了/解決されたプロミス」である必要があります。現在、上記のコードの最初のセットを使用してそれを行っています。もっと良い方法があるに違いないようです。

4

2 に答える 2

31

単に解決済みの promisereturn $.when();を返すために使用します。

引数をまったく渡さない場合、jQuery.when() は解決された promise を返します。

参考: https ://api.jquery.com/jquery.when/


ノート:

  • これは、return $.when(undefined);配列とapply.

可変数のプロミスが並行して完了するのを待ちたい場合は、このパターンをループで使用できます。

var promise;   // Undefined is treated as an initial resolved promise by $.when
while (insomeloop){
    promise = $.when(promise, newpromise);
}

次に、完了時に次のように最終呼び出しを行います。

promise.then(function(){
    // All done!
});

例えば

var promise;$.when
var $elements = $('.some-elements');
$elements.each(function(){
     var $element = $(this).fadeout();
     promise = $.when(promise, $element.promise());
});
promise.then(function(){
    // All promises completed!
});

欠点はマイナーです。

  • を呼び出すたびにwhen、前の promise が新しい promise にラップされます。わずかなオーバーヘッドで、promise の配列を維持および評価する必要がなくなります。
  • 最終関数に値を直接渡すことはできません。通常、並列 promisesからの戻り値は必要ないため、これはマイナーです。
  • 1 つの Promise が失敗すると、最後の待機が早期に中止されるため、すべての Promise が確実に実行されるようにする必要があります。
于 2015-11-11T17:50:05.420 に答える