LoginSignup
36
37

More than 5 years have passed since last update.

jQuery.Deferredを使って非同期ループ!

Last updated at Posted at 2013-06-06

jQuery.Deferredのお勉強にもどうぞ!
フォロー、コメントお待ちしてます

jquery-asyncEach.js
if(jQuery) !function($){
    'use strict';
    if( typeof $.asyncEach === 'undefined' ){
        // setTimeoutとDeferredを使い非同期にする関数
        var async = function($callback){
            var $dfd = $.Deferred();
            setTimeout(function(){
                $callback($dfd);
            },0);
            return $dfd.promise();
        };
        // $.asyncEachメソッド本体
        $.asyncEach = function($array,$callback,$thisArg){
            if( typeof $thisArg === 'undefined' ) $thisArg = $array;
            //$arrayが大量だった時に$whenを作るのに時間がかかるのでいきなり非同期化
            return async(function($dfd){
                //$arrayの要素を1個づつ非同期化
                var $when   = $.map($array,function($value,$index){
                    return async(function($dfd){
                        return $callback.call($thisArg,$dfd,$value,$index);
                    });
                });
                //$whenが全てresolveするとdone、ひとつでもrejectするとfailする
                return $.when.apply($,$when)
                    .done(function(){
                        //argumentsを配列に変換して返す
                        var $_ = [];
                        $_.push.apply($_,arguments);
                        return $dfd.resolve($_);
                    })
                    .fail(function(){
                        var $_ = [];
                        $_.push.apply($_,arguments);
                        return $dfd.reject($_);
                    })
                ;
            });
        };
    }
}(jQuery);
テストコード
!function(){
    console.log('最初に表示される');
    $.asyncEach([1,2,3,4,5,6,7,8,9,10],function($dfd,$value,$index){
        //ここに重い処理(…の、かわりにランダムで待たせてから返す)
        var $r = Math.floor( Math.random() * 1050 );
        setTimeout(function(){
            //どちらかを使って返り値を返す
            // $dfd.resolve() = 処理成功
            // $dfd.reject()  = 処理失敗
            return $r <= 1000
                ? $dfd.resolve($value * 2)
                : $dfd.reject($value + 'がキモイ');
        },$r);
    }).then(//.done,.failでもいい
        function($result){
            console.log('重い処理が全部終わったら呼ばれる');
            console.log($result);
        },function($result){
            console.log('途中でrejectされたら呼ばれる');
            console.log($result);
        }
    );
    console.log('asyncEachは非同期なので2番目に表示される');
}()
36
37
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36
37