1. ホーム
  2. ジャバスクリプト

[解決済み】jQuery deferredはどのように使用することができますか?

2022-04-01 06:38:42

質問

jQuery 1.5では、新しいDeferredオブジェクトと付属のメソッドが追加されました。 .when , .Deferred そして ._Deferred .

を使ったことがない人のために .Deferred をアノテーションしています。 ソース .

これらの新しいメソッドは、どのような使い方が考えられるのか、どのようにパターンに当てはめればいいのか。

を既に読んでいます。 API ソース だから、それが何をするものなのかは知っています。質問は、これらの新機能を日常的なコードでどのように使用できるかということです。

私は単純な AJAXリクエストを順番に呼び出すバッファークラス。(前のものが終了した後、次のものが始まります)。

/* Class: Buffer
 *  methods: append
 *
 *  Constructor: takes a function which will be the task handler to be called
 *
 *  .append appends a task to the buffer. Buffer will only call a task when the 
 *  previous task has finished
 */
var Buffer = function(handler) {
    var tasks = [];
    // empty resolved deferred object
    var deferred = $.when();

    // handle the next object
    function handleNextTask() {
        // if the current deferred task has resolved and there are more tasks
        if (deferred.isResolved() && tasks.length > 0) {
            // grab a task
            var task = tasks.shift();
            // set the deferred to be deferred returned from the handler
            deferred = handler(task);
            // if its not a deferred object then set it to be an empty deferred object
            if (!(deferred && deferred.promise)) {
                deferred = $.when();
            }
            // if we have tasks left then handle the next one when the current one 
            // is done.
            if (tasks.length > 0) {
                deferred.done(handleNextTask);
            }
        }
    }

    // appends a task.
    this.append = function(task) {
        // add to the array
        tasks.push(task);
        // handle the next task
        handleNextTask();
    };
};

のデモや可能な使い方を探しています。 .Deferred.when .

の例も見てみたいものです。 ._Deferred .

リンク先が新しい jQuery.ajax のソースを例にとると、ズルいですね。

特に、ある操作が同期で行われるか非同期で行われるかを抽象化したときに、どのようなテクニックがあるのかに興味があります。

どのように解決するのか?

私が思いつく最も良い使用例は、AJAXレスポンスをキャッシュすることです。 以下は、以下の例を修正したものです。 Rebecca Murpheyのイントロダクション記事 :

var cache = {};

function getData( val ){

    // return either the cached value or jqXHR object wrapped Promise
    return $.when(
        cache[ val ] || 
        $.ajax('/foo/', {
            data: { value: val },
            dataType: 'json',
            success: function( resp ){
                cache[ val ] = resp;
            }
        })
    );
}

getData('foo').then(function(resp){
    // do something with the response, which may
    // or may not have been retrieved using an
    // XHR request.
});

基本的に、その値が以前に一度リクエストされている場合は、キャッシュからすぐに返されます。 そうでない場合は、AJAXリクエストでデータを取得し、キャッシュに追加します。 そのため $.when / .then はこのようなことは一切気にしません。 .then() ハンドラです。 jQuery.when() は、非 Promise/Deferred を Completed として処理し、直ちにすべての .done() または .then() をチェーン上に表示します。

Deferredsはタスクが非同期で動作するかしないか、その条件をコードから抽象化したい場合に最適です。

を使用したもう一つの実例は $.when ヘルパーを使用します。

$.when($.getJSON('/some/data/'), $.get('template.tpl')).then(function (data, tmpl) {

    $(tmpl) // create a jQuery object out of the template
    .tmpl(data) // compile it
    .appendTo("#target"); // insert it into the DOM

});