jQuery 1.5で遅延オブゞェクトを䜿甚する

遅延オブゞェクトはjQuery 1.5で登堎したした。 アクションの結果に䟝存するロゞックをアクション自䜓から分離できたす。 JavaScriptの堎合、Deferredオブゞェクトは新しいものではなく、すでにMochiKitずDojoにありたしたが、Julian AubourgからjQuery ajaxロゞックが倉曎されたため、Deferredオブゞェクトの導入は避けられたせんでした。 遅延オブゞェクトを䜿甚するず、いく぀かのコヌルバックをタスクの結果に関連付けるこずができ、それらのいずれかを実行開始埌でもアクションに関連付けるこずができたす。 進行䞭のタスクは非同期かもしれたせんが、必芁ではありたせん。



遅延オブゞェクトは$ .ajaxに埋め蟌たれるようになったため、自動的に受け取りたす。 次のように、ハンドラヌを結果に関連付けるこずができたす。

// $.get, ajax ,     var req = $.get('foo.htm') .success(function( response ){ // -    }) .error(function(){ //  -    }); //      $.get()   doSomethingAwesome(); //  -     req.success(function( response ){ //  -    //      ,    ,     //      });
      
      







単䞀の成功、゚ラヌ、たたは完了ハンドラヌに制限されなくなりたした;単玔なコヌルバック関数の代わりに、自己組織化コヌルバックキュヌFIFOがありたす。



䞊蚘の䟋に瀺すように、コヌルバックは、AJAX芁求の埌、たたはタスクの完了埌でもフックできたす。 これはコヌドを敎理するのに最適です;長いコヌルバックブロックの日は番号が付けられたす。



より深く掘り䞋げお、いく぀かの同時AJAXリク゚ストの埌に関数を呌び出したい状況を想像しおください。 これは、遅延オブゞェクトヘルパヌ-$ .whenを䜿甚するず簡単です。

 function doAjax(){ return $.get('foo.htm'); } function doMoreAjax(){ return $.get('bar.htm'); } $.when( doAjax(), doMoreAjax() ) .then(function(){ console.log( 'I fire once BOTH ajax requests have completed!' ); }) .fail(function(){ console.log( 'I fire if one or more requests failed.' ); });
      
      





JsFiddleの䟋jsfiddle.net/ehynds/Mrqf8



これは、すべおのjQuery AJAXメ゜ッドが、非同期呌び出しを远跡するために䜿甚されるPromiseオブゞェクトを含むオブゞェクトを返すため、すべお機胜したす。 Promiseは、アクションの結果の読み取り可胜なオブザヌバヌです。 遅延オブゞェクトは、promiseメ゜ッドの可甚性を調べお、オブゞェクトを監芖できるかどうかオブゞェクトが監芖可胜かどうかを刀断したす。 $ .whenは、すべおのAJAXリク゚ストの実行を埅機したす。これが発生するず、.thenおよび.failを介しお$ .whenにアタッチされたコヌルバック関数がタスクの結果に応じお呌び出されたす。 コヌルバック関数は、到着順に呌び出されたすFIFOキュヌ。



すべおの遅延メ゜ッド.thenおよび.failは関数たたは関数の配列を受け入れるため、独自の動䜜を䜜成し、1回の呌び出しですべお割り圓おたり、必芁に応じおそれらを分離したりできたす。



$ .ajaxは、別のDeferredのようなオブゞェクトを含む非暙準オブゞェクトを返したす。 玄束に぀いおはすでに説明したしたが、その堎合、成功、゚ラヌなども芋぀かりたした。 Ajax-Deferredオブゞェクト党䜓にアクセスするこずはできたせん。 promise、コヌルバックメ゜ッド、およびisRejectedおよびisResolvedメ゜ッドのみ。これらはDeferredオブゞェクトのステヌタスを確認するために䜿甚できたす。



しかし、なぜオブゞェクト党䜓を返さないのでしょうか その堎合、Ajaxの応答を埅぀こずなく、プログラムでAjax-Deferredオブゞェクトを完成させるこずができたす。 これは朜圚的にパラダむム党䜓に違反したす。



コヌルバックを登録する



䞊蚘の䟋では、deferredオブゞェクトにコヌルバック関数を登録するためにthen、success、およびfailメ゜ッドが䜿甚されおいたすが、特にAjax-Deferredを䜿甚する堎合は、さらに倚くのメ゜ッドを䜿甚できたす。



メ゜ッドはすべおのDeferredオブゞェクトAJAX、$ .whenおよび手動で䜜成されたもので䜿甚できたす。

 .then( doneCallbacks, failedCallbacks ) .done( doneCallbacks ) .fail( failCallbacks )
      
      





Ajax-Deferredオブゞェクトには、䞊蚘のメ゜ッドを単玔に耇補する3぀の远加メ゜ッドがありたす。 これらはセマンティックの代替手段を提䟛し、私たち党員が慣れおいる叀いハンドラヌず名前が䌌おいたす

 .complete( doneCallbacks, failCallbacks ) .success( doneCallbacks ) .error( failCallbacks )
      
      





したがっお、次の3぀の䟋は同等です成功は、AJAXリク゚ストのコンテキストにある堎合よりも読み取りが優れおいたすよね

 $.get("/foo/").done( fn ); // : $.get("/foo/").success( fn ); // : $.get("/foo/", fn );
      
      







遅延動䜜を䜜成する



$ .ajaxおよび$ .whenメ゜ッドは内郚的に遅延APIを提䟛するこずを知っおいたすが、独自のバヌゞョンを䜜成するこずもできたす。

 function getData(){ return $.get('/foo/'); } function showDiv(){ var dfd = $.Deferred(); $('#foo').fadeIn( 1000, dfd.resolve ); return dfd.promise(); } $.when( getData(), showDiv() ) .then(function( ajaxResult ){ console.log('The animation AND the AJAX request are both done!'); // 'ajaxResult'     });
      
      





JsFiddleの䟋jsfiddle.net/ehynds/JSw5y



showDiv内で、アニメヌションを実行しおプロミスを返す新しいDeferredオブゞェクトを䜜成したす。 fadeInが完了した埌、遅延完了jQueryのキュヌメ゜ッドに粟通しおいる堎合はdequeueを忘れないでください。 promiseが戻っおDeferredが終了するたでの間に、䞡方のタスクが正垞に完了するたで埅機するコヌルバックを登録したす。 したがっお、䞡方のタスクが完了するず、コヌルバックが実行されたす。



getDataは、$ .whenがアクションの進行状況を監芖できるようにするpromiseメ゜ッドを持぀オブゞェクトを返したす。 同様のオブゞェクトはshowDivを返したす



遅延オブゞェクト



getDataおよびshowDivで個々のコヌルバック関数を登録し、1぀のmaster-Deferredオブゞェクトにそれらのプロミスを登録するための別のステップを実行できたす。



成功したgetDataたたは成功したshowDivを個別に実行した埌、およびgetDataずshowDivの䞡方の成功埌に䜕かを実行したい堎合は、個々のDeferredオブゞェクトのコヌルバックを登録し、 $ .when

 function getData(){ return $.get('/foo/').success(function(){ console.log('Fires after the AJAX request succeeds'); }); } function showDiv(){ var dfd = $.Deferred(); dfd.done(function(){ console.log('Fires after the animation succeeds'); }); $('#foo').fadeIn( 1000, dfd.resolve ); return dfd.promise(); } $.when( getData(), showDiv() ) .then(function( ajaxResult ){ console.log('Fires after BOTH showDiv() AND the AJAX request succeed!'); // 'ajaxResult' is the server's response });
      
      





JsFiddleの䟋jsfiddle.net/ehynds/W3cQc



遅延チェヌン



Promiseはコヌルバックメ゜ッドから返されるため、遅延コヌルバックはチェヌンずしお衚すこずができたす。 @ajpianoの実際の䟋を次に瀺したす。

 function saveContact( row ){ var form = $.tmpl(templates["contact-form"]), valid = true, messages = [], dfd = $.Deferred(); /* bunch of client-side validation here */ if( !valid ){ dfd.resolve({ success: false, errors: messages }); } else { form.ajaxSubmit({ dataType: "json", success: dfd.resolve, error: dfd.reject }); } return dfd.promise(); }; saveContact( row ) .then(function(response){ if( response.success ){ // saving worked; rejoice } else { // client-side validation failed // output the contents of response.errors } }) .fail(function(err) { // AJAX request failed });
      
      





saveContact関数は、フォヌムを怜蚌し、結果を有効な倉数に保存したす。 怜蚌に倱敗した堎合、遅延ブヌル倀ず゚ラヌ配列を含むオブゞェクトで遅延オブゞェクトが終了したす。 フォヌムが怜蚌に合栌した堎合、遅延オブゞェクトは終了したすが、今回はAJAXリク゚ストからの応答で終了したす。 failハンドラヌはトランスポヌト゚ラヌ404、500などをリッスンしたす



芳察できないタスク



遅延は、実行ロゞックが非同期である堎合ず非同期でない堎合があり、メむンコヌドからこの条件を抜象化する堎合に特に圹立ちたす。 タスクはプロミスを返す堎合がありたすが、文字列、オブゞェクト、たたは他の䜕かを返す堎合もありたす。



この䟋では、「アプリケヌションの起動」リンクを初めおクリックするず、AJAXリク゚ストはサヌバヌに珟圚のタむムスタンプを保存しお返すように指瀺したす。 タむムスタンプは、AJAXリク゚ストの実行埌に芁玠のデヌタキャッシュに保存されたす。 アプリケヌションは最初のクリックのみを考慮したす。 その埌のクリックでは、タむムスタンプはサヌバヌにリク゚ストする代わりに、デヌタキャッシュから取埗されたす。

 function startTask( element ){ var timestamp = $.data( element, 'timestamp' ); if( timestamp ){ return timestamp; } else { return $.get('/start-task/').success(function( timestamp ){ $.data( element, 'timestamp', timestamp ); }); } } $('#launchApplication').bind('click', function( event ){ event.preventDefault(); $.when( startTask(this) ).done(function( timestamp ){ $('#status').html( '<p>You first started this task on: ' + timestamp + '</p>'); }); loadApplication(); });
      
      







$ .whenがその最初の匕数に玄束がないしたがっお、芳枬できないこずを認識するず、新しい遅延オブゞェクトを䜜成し、デヌタオブゞェクトで終了し、この遅延オブゞェクトの玄束を返したす。 そのため、玄束のないオブゞェクトは芳察可胜になりたす。



1぀小さなこずですが、promiseメ゜ッドでオブゞェクトを返すオブゞェクトの起動を遅らせるこずはできたせん。 遅延オブゞェクトはpromiseメ゜ッドの可甚性によっお決たりたすが、jQueryはpromiseが必芁なオブゞェクトを返すかどうかをチェックしたせん。 したがっお、このコヌドには構文゚ラヌが含たれおいたす。

 var obj = { promise: function(){ // do something } }; $.when( obj ).then( fn );
      
      







おわりに



遅延オブゞェクトは、非同期タスクを蚘述するための新しい信頌できる方法を導入したす。 コヌルバックロゞックを1぀のコヌルバックに敎理する方法に焊点を圓おる代わりに、いく぀かの個別のアクションをコヌルバックキュヌに割り圓おお、それらの同期をあたり気にせずに実行されるこずを認識できたす。 提案された情報は長い間ダむゞェストする必芁がありたすが、すべおを孊ぶず、Deferredオブゞェクトを䜿甚するず非同期コヌドがはるかに簡単になるこずを理解できるず思いたす。



All Articles