非同期コールバックにおける jQuery の Promise と遅延オブジェクトの役割_jquery
1. はじめに
フロントエンドをコールバックの地獄から天国に戻すために、jQuery は Promise の概念も導入しました。 Promise は、コードの非同期動作をよりエレガントにする抽象化であり、同期コードを作成するのと同じように非同期コードを作成できます。 jQuery は、バージョン 1.5 以降、強力なソリューションとして CommonJS Promise/A 仕様を実装していますが、仕様に厳密に従って実装されておらず、API にいくつかの違いがあります。
それでは、その機能を見てみましょう (この記事の例は、jquery バージョン 1.8 以降に基づいています)。
2. 例
これまでアニメーションを作成するときは、通常次のようにしていました:
$('.animateEle').animate({ opacity:'.5' }, 4000,function(){ $('.animateEle2').animate({ width:'100px' },2000,function(){ // 这样太伤了 $('.animateEle3').animate({ height:'0' },2000); }); });
コールバックがこのように使用されると、あまりにも有害です。幸いなことに、この問題をエレガントに解決する、すぐに使える Promise ソリューションがいくつかあります。
jQuery が提供するソリューションを見てみましょう。
var animate1 = function() { return $('.animateEle1').animate({opacity:'.5'},4000).promise(); }; var animate2 = function() { return $('.animateEle2').animate({width:'100px'},2000).promise(); }; var animate3 = function(){ return $('.animateEle3').animate({height:'0'},2000).promise(); }; // so easy,有木有,so clear,有木有 $.when(animate1()).then(animate2).then(animate3);
明らかに、変更されたコードは理解しやすく、読みやすくなっています。
ただし、上記のコードでは一部の詳細が公開されていないため、注意しないと間違いを犯しやすく、アニメーションを希望の順序で完了する効果が得られません。 jQueryが提供するpromiseオブジェクトとdeferredオブジェクトのメソッドをしっかり理解して使い方を見てみましょう。
3. Promise および遅延オブジェクト メソッド
Promise オブジェクトは非同期状態を変更できませんが、遅延オブジェクトは変更できるため、Promise オブジェクトは実際には遅延オブジェクトの特殊なケースです。これは彼らのメソッド設計に明確に反映されています。
1.promise オブジェクトメソッド
通常、DOM、アニメーション、Ajax 関連のメソッドには、Promise メソッドを使用できます。 Promise メソッドを呼び出すと、Promise オブジェクトが返されます。 Promise メソッドはチェーン内で呼び出すことができます。
Promise オブジェクトには、done、fail、then の 3 つの一般的なメソッドがあります。
他のメソッドについても忘れないでください。jquery には非常に冗長なインターフェイス メソッドがあり、初期のイベント メソッド バインディングと同様に、live、delegate、bind は最終的にすべて分類されるわけではありません。オンがここで対応してくれる?
コード例は次のとおりです:
(1) DOM は Promise メソッドを使用します:
var box=$('#box'); box.promise().done(function(ele){ console.log(ele);//jQuery box });
(2) Ajax は Promise メソッドを使用します (デフォルトで Promise オブジェクトを返すため、Promise メソッドを明示的に呼び出す必要はありません)。
$.post('/',{}).done(function(data){ console.log('请求成功'); }).fail(function(){ console.log('请求错误'); });
アニメーションの例はすでに存在するため、再度リストすることはしません。
2.遅延オブジェクトメソッド
それでは、Deferred と Promise の違いは何でしょうか?前に見たように、Promise は非同期関数によって返されるオブジェクトです。このような関数を自分で書きたい場合は、deferred を使用する必要があります。
遅延オブジェクトは Promise オブジェクトと同じことを実行できますが、done() 関数とfail() 関数をトリガーする 2 つの関数があります。
遅延オブジェクトには、成功した結果を処理し、done() に関連する関数を実行するための replace() 関数があります。 request() 関数は、失敗した結果を処理し、fail() に関連する関数を実行するために使用されます。
resolve() 関数とreject() 関数の両方にパラメータを指定すると、それらは両方ともdone() とfail() に関連するコールバック関数に渡されます。
Promise オブジェクトには、resolve() 関数とreject() 関数がありません。これは、Promise を別のスクリプトに入れており、Promise によって Promise が解決または拒否されることを望まないためです。
以下は deferred の簡単な例です。 html は、「result」の id 属性を持つ単純な空の div です。
$('#result').html('waiting...'); var promise = wait(); promise.done(result); function result() { $('#result').html('done'); } function wait() { var deferred = $.Deferred(); setTimeout(function() { deferred.resolve(); }, 2000); return deferred.promise(); }
このうち、wait() 関数は Promise を返します。 2秒後に解析されます。 setTimeout に加えて、アニメーション、Web ワーカーなど、非同期関数のすべてをこの方法で使用できます。 wait() 関数のコードは明確である必要があります。遅延オブジェクトを使用しますが、制限付きの Promise オブジェクトを返します。
遅延オブジェクト、つまり $.Deferred() メソッドと $.when() メソッドを使用して作成されたオブジェクトの場合、一般的に使用される次のメソッドがあります。
resolve , reject , notify ; done , fail , progress ;
promise 、 then 、および always メソッドもあります。
これらがこのようにフォーマットされている理由は、それらが対応しているためです。つまり、resolve メソッドは、done のコールバック実行をトリガーし、reject は、fail のコールバックをトリガーし、notify は、progress のコールバックをトリガーします。
コードを直接見てください:
var wait = function(ms) { var dtd = $.Deferred(); setTimeout(dtd.resolve, ms); // setTimeout(dtd.reject, ms); // setTimeout(dtd.notify, ms); return dtd.promise(); //此处也可以直接返回dtd }; wait(2500).done(function() { console.log('haha,师太,你可让老衲久等了'); }).fail(function() { console.log('失败了'); }).progress(function(res) { console.log('等待中...'); });
我们看到了,上面的代码中,在 wait 函数中,返回的是个 promise 对象,而不是 deferred 对象。
要知道, promise 对象是没有 resolve , reject , notify 等方法的,也就意味着,你无法针对 promise 对象进行状态更改,只能在 done 或 fail 中进行回调配置。所以,你如果这么调用 wait(2500).resolve() 将会报错,因为 wait(2500) 返回的是个 promise 对象,不存在 resolve 方法。
但是,这么做,有个好处,我们把 dtd 这个 deferred 对象放在了 wai t函数中,作为了局部变量,避免了全局的污染;进一步通过 promise 方法,转化 dtd 这个 deferred 对象为 promise 对象,避免了函数 wait 外部可能发生的状态更改(假如我们确实有这个需求)。
比如:
var wait = function(ms) { var dtd = $.Deferred(); setTimeout(dtd.resolve, ms); // setTimeout(dtd.reject, ms); // setTimeout(dtd.notify, ms); return dtd; //此处也可以直接返回dtd }; wait(2500).reject().fail(function(){ console.log('失败了...............'); });
我们在外部更改了 wait 返回的 deferred 对象的状态,这样必然触发该对象的 fail 回调函数。
对于 always 方法,从字面意思上就很容易理解, deferred 对象无论是 resolve 还是 reject ,都会触发该方法的回调。
3.其它共性
此处讲讲 then 和 $.when 方法的使用。它们对 promise 对象也适用。
$.when 方法接受多个 deferred 对象或者纯javascript对象,返回 promise 对象。
then 方法依次接受三个回调,分别为 deferred 对象 resolve , reject , notify 后触发的回调,返回一个 promise 对象。注意,必须传入函数,而该函数只有返回一个 promise 对象,才能够让异步事件按照预期顺序来执行。
我们来看看最开始的动画示例代码, $.when(animate1()).then(animate2).then(animate3) , $.when 方法中接受了一个 animate1 的函数执行结果,也就是得到了一个 promise 对象,而后的 then 中,则只是接受了一个变量名,这样得到的结果是一个匿名的函数体,而该函数中返回的是 promise 对象。正好符合了我们对 then 接受参数的要求。
假如我们把执行语句改成: $.when(animate1()).then(animate2()).then(animate3()) ,这样造成的结果就是三个动画同步执行了。与 $.when(animate1(),animate2(),animate3()) 无异。
既然 then 是如此要求,那么与 then 方法类似的 done , fail , progress 也是一样的。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











jQueryでPUTリクエストメソッドを使用するにはどうすればよいですか? jQuery で PUT リクエストを送信する方法は、他のタイプのリクエストを送信する方法と似ていますが、いくつかの詳細とパラメータ設定に注意する必要があります。 PUT リクエストは通常、データベース内のデータの更新やサーバー上のファイルの更新など、リソースを更新するために使用されます。以下は、jQuery の PUT リクエスト メソッドを使用した具体的なコード例です。まず、jQuery ライブラリ ファイルが含まれていることを確認してから、$.ajax({u

jQueryで要素の高さ属性を削除するにはどうすればよいですか?フロントエンド開発では、要素の高さ属性を操作する必要が生じることがよくあります。要素の高さを動的に変更する必要がある場合や、要素の高さ属性を削除する必要がある場合があります。この記事では、jQuery を使用して要素の高さ属性を削除する方法と、具体的なコード例を紹介します。 jQuery を使用して高さ属性を操作する前に、まず CSS の高さ属性を理解する必要があります。 height 属性は要素の高さを設定するために使用されます

タイトル: jQuery ヒント: ページ上のすべての a タグのテキストをすばやく変更する Web 開発では、ページ上の要素を変更したり操作したりする必要がよくあります。 jQuery を使用する場合、ページ内のすべての a タグのテキスト コンテンツを一度に変更する必要がある場合があります。これにより、時間と労力を節約できます。以下では、jQuery を使用してページ上のすべての a タグのテキストをすばやく変更する方法と、具体的なコード例を紹介します。まず、jQuery ライブラリ ファイルを導入し、次のコードがページに導入されていることを確認する必要があります: <

タイトル: jQuery を使用して、すべての a タグのテキスト コンテンツを変更します。 jQuery は、DOM 操作を処理するために広く使用されている人気のある JavaScript ライブラリです。 Web 開発では、ページ上のリンク タグ (タグ) のテキスト コンテンツを変更する必要が生じることがよくあります。この記事では、この目標を達成するために jQuery を使用する方法を説明し、具体的なコード例を示します。まず、jQuery ライブラリをページに導入する必要があります。 HTML ファイルに次のコードを追加します。

同時プログラミングと非同期プログラミング 同時プログラミングは、同時に実行される複数のタスクを扱います。非同期プログラミングは、タスクがスレッドをブロックしない同時プログラミングの一種です。 asyncio は Python の非同期プログラミング用のライブラリで、プログラムがメイン スレッドをブロックせずに I/O 操作を実行できるようにします。イベント ループ asyncio の中核は、I/O イベントを監視し、対応するタスクをスケジュールするイベント ループです。コルーチンの準備が完了すると、イベント ループは I/O 操作を待つまでそのコルーチンを実行します。その後、コルーチンを一時停止し、他のコルーチンの実行を継続します。コルーチン コルーチンは、実行を一時停止および再開できる関数です。 asyncdef キーワードは、コルーチンの作成に使用されます。コルーチンは await キーワードを使用して、I/O 操作が完了するのを待ちます。 asyncio の次の基本

jQuery は、Web ページでの DOM 操作やイベント処理を処理するために広く使用されている人気のある JavaScript ライブラリです。 jQueryではeq()メソッドを利用して指定したインデックス位置の要素を選択しますが、具体的な使い方と応用シーンは以下の通りです。 jQuery では、 eq() メソッドは、指定されたインデックス位置にある要素を選択します。インデックス位置は 0 からカウントされます。つまり、最初の要素のインデックスは 0、2 番目の要素のインデックスは 1 などとなります。 eq() メソッドの構文は次のとおりです。 $("s

非同期および非ブロッキング技術を使用して、従来の例外処理を補完し、より応答性が高く効率的な Java アプリケーションを作成できます。 非同期例外処理: 別のスレッドまたはプロセスで例外を処理し、メイン スレッドが実行を継続できるようにして、ブロックを回避します。ノンブロッキング例外処理: I/O 操作が失敗した場合のイベント駆動型の例外処理が含まれ、スレッドのブロックを回避し、イベント ループで例外を処理できるようにします。

利点: 非同期で非ブロッキングなので、メインスレッドをブロックしません。組み込みのエラー処理メカニズムが向上します。
