jQueryコールバック、繰延対象まとめ(次編)——jQueryを解読する.whenメソッド

10640 ワード

前言:
前の文章ではthen方法を重点的にまとめ、主に複数の非同期タスクを処理して順番に実行するために使用されています.すなわち、前のタスクが処理された後、次のタスクに進みます.
この章ではwhenメソッドも複数の非同期タスクを処理し、複数の非同期タスク(Promiseオブジェクト)を1つのPromiseオブジェクトにマージします.このマージ後のPromiseオブジェクト
どのようにしてステータスを更新しますか?つまり、いつ実行し、拒否しますか?下を見続けましょう.
 
jQueryコールバック、繰延対象総括編索引:
jQueryコールバック、繰延対象まとめ(前編)——jQuery.Callbacks
jQueryコールバック、繰延対象まとめ(中編)——不思議なthen方法
jQueryコールバック、繰延対象まとめ(次編)——jQueryを解読する.whenメソッド
 
せっけい構想
jQueryを実行する.whenはPromiseオブジェクトを返します.whenによって生成されたPromiseオブジェクトと呼ばれます.指定されたすべてのPromiseオブジェクトが実行されたら、すぐに実行します.
whenメソッドによって生成されたPromiseオブジェクトは,与えられたPromiseオブジェクトのいずれかが拒否されると,whenによって生成されたPromiseオブジェクトを直ちに拒否するという意図である.
指定された複数の非同期イベントが完了してから、自分のやりたいことをする必要があるようです.
 
ソース解析
jQuery.extend({
    // Deferred helper
    //    Promise  ,    :   Promise  
    // when     deferred  ,    : when   Promise  
    when: function( subordinate /* , ..., subordinateN */ ) {
        var i = 0,
            resolveValues = core_slice.call( arguments ),
            length = resolveValues.length,
            // the count of uncompleted subordinates
            //           (  ) Promise     
            remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,

            // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
            //    deferred when   Promise  
            deferred = remaining === 1 ? subordinate : jQuery.Deferred(),

            // Update function for both resolve and progress values
            updateFunc = function( i, contexts, values ) {
                return function( value ) {
                    contexts[ i ] = this;
                    values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
                    //          Promise        ,    when   Promise   pending  
                    //  :contexts       Promise       ,
                    // values         Promise             
                    if( values === progressValues ) {
                        deferred.notifyWith( contexts, values );
                    }
                    //      Promise     (  ),      Promise     0,
                    //  :     Promise      (  ),      when   Promise  
                    //  :contexts       Promise       ,
                    // values         Promise             (    1)
                    else if ( !( --remaining ) ) {
                        deferred.resolveWith( contexts, values );
                    }
                };
            },

            progressValues, progressContexts, resolveContexts;

        // add listeners to Deferred subordinates; treat others as resolved
        if ( length > 1 ) {
            progressValues = new Array( length );
            progressContexts = new Array( length );

            // resolveValues = core_slice.call( arguments ) //            
            resolveContexts = new Array( length );
            for ( ; i < length; i++ ) {
                //     when      Promise  ,    when   Promise  ,    ,    ?
                //      Promise     ,    when   Promise  (       Promise      )
                //          Promise     ,    when   Promise  
                //         ,   pending  
                if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
                    resolveValues[ i ].promise()
                        .done( updateFunc( i, resolveContexts, resolveValues ) )
                        .fail( deferred.reject )
                        .progress( updateFunc( i, progressContexts, progressValues ) );
                }
                //          Promise  ,      
                else {
                    --remaining;
                }
            }
        }

        // if we're not waiting on anything, resolve the master
        //      when          ,    when   Promise  
        if ( !remaining ) {
            // resolveContexts      new Array( length ),resolveValues  when         
            deferred.resolveWith( resolveContexts, resolveValues );
        }

        return deferred.promise();
    }
});

 
例:whenによって生成されたPromiseオブジェクトのパラメータを実行する問題について
var promiseA = $.Deferred();
var promiseB = $.Deferred();

var doneFn = function(arg){
    console.log(arg);
};

promiseA.done(doneFn);
promiseB.done(doneFn);

promiseA.resolve('A'); // 'A'
promiseB.resolve('B'); // 'B'

var whenFn = function(arg1, arg2){
    console.log(this[0] === promiseA.promise()); // true
    console.log(this[1] === promiseB.promise()); // true
    console.log('promise' + arg1 + ', promise' + arg2 + ' All done!');
};
var whenPromise = jQuery.when(promiseA, promiseB);
whenPromise.done(whenFn); // true true 'promiseA, promiseB All done!'

 
jQueryコールバック、繰延対象まとめ:
繰延オブジェクトにおけるthenメソッドは、複数の非同期タスクを順番に実行することに作用し、jQuery.whenメソッドは、複数の同時非同期タスクが実行された後、自分の興味のあることをするのに役立ちます.
jQuery繰延オブジェクトはjQueryコールバックオブジェクトアーキテクチャに基づいています.jQuery繰延オブジェクトを熟練したい場合は、まずjQueryに移動してください.Callbacksオブジェクト
 
 
PS:説明が間違っていたら訂正してください.分からないところがあればメールを送ってください.
転載する必要がある場合は、本文の住所と出典:ブログ園華子yjhを添付してください.ありがとうございます.