【jQuery】Deferredを使って、アニメーションやAjaxの処理をいい感じに書く

ウェブ制作技術

おはようございます、樋口です。
今日はJavascriptの話です。

アニメーションやAjax(非同期処理)は、Webアプリケーション制作においてなくてはならないものですが、往々にして処理が複雑になりがちです。
「アニメーションAのあとアニメーションB、そのあとajaxでapiをたたいて、返ってきたらそれを使ってアニメーションC」とか。

こういう連鎖をふつうに書くと、コールバック関数を連発しまくらないといけないです。

これを解決するのが、jQueryの「Deferred」インターフェース、そして「Promise」です。

Javascript

DeferredとPromise

Deferredオブジェクト

jQueryでDeferredを使うには、まずDeferredオブジェクトを作ります
作り方は、こうです。

これでDeferredオブジェクトができました。
Deferredオブジェクトである変数dfdを使って、非同期の処理を作っていきます。

Promiseオブジェクト

Deferredオブジェクトは、「Promise」というオブジェクトを持ちます。
そしてこのPromiseオブジェクトは、「状態」を保持しています。

  • pending:なんの処理もされていない状態
  • resolved:正常に処理が完了した状態
  • rejected:処理が失敗した状態

これらの状態が変化することで、状態に対応した処理を実行するしくみです。

プログラミング

コードを見てみます。

基本の流れは、3つのステップに分けられます。

【1】Deferredオブジェクトをつくり
【2】状態を変化(resolvedに)
【3】Promiseオブジェクトを介して、then()でその後の処理につなげる

プログラミング

ちなみに【2】で、resolveではなく

とした場合、状態は「rejected」となります。

resolveまたはrejectという状態の変化に応じて、その後の処理が変わります。

done()とfail()

上記の例で、then()によりpromiseの状態変化後の処理を設定する、と書きました。
が、thenの前に、done()とfail()を説明します。

done()・・・promiseがresolvedのときに実行
fail()・・・promiseがrejectedのときに実行

前述のコードにdone()とfail()を加えると、こうなります。

done()とfail()にそれぞれ処理を登録していますが、上記例ではpromiseはresolvedなので、実行されるのはdone()の処理だけです。
fail()の方は無視されます。

then()

で、then()の話です。
then()の特徴は、大きく2つあります。

  • doneとfailを同時に登録できる
  • 新しいPromiseを返すので、処理を連結できる

doneとfailを同時に登録できる

then()は、第一引数にdone()を、第二引数にfail()を登録できます。

第二引数は省略可能です。その場合、done()のみが登録されます。

新しいPromiseを返すので、処理を連結できる

then()が強力なのは、処理をつなげて書けることです。

プログラミング

こうすると処理A、B、Cを順番に実行してくれます。
なぜthenで処理をつなげて書けるのかというと、then()が新しいpromiseオブジェクトを返すからです。
promiseオブジェクトに対しては、then()はもちろん、done()やfail()も使えます。

then = それから という日本語訳もあてはめられるので、「promiseがresolvedになった、それから、A、それから、B、それから、C」というイメージでしょうか。

when()

then()よりもっと強力なのが、when()です。
なにが強力なのかというと、処理を並列にできるからです。

みたいな感じで書けます。
処理A、B、Cが並んで処理され、それらをまとめたpromiseオブジェクトが返ります。
primiseが返されるので、.then(処理D)とつなげられるわけです。

プログラミング

処理A、B、Cがすべて「resolved」になったとき、promiseオブジェクトも「resolved」になります。
処理A、B、Cが一つでも「rejected」の場合は、まとめたpromiseオブジェクトも「rejected」になります。

whenをうまく使うと、複雑な処理も分かりやすく書けそうです。

$.ajaxの返り値

ひととおり用語を紹介したところで、Ajaxの処理の仕方についてみてみます。

非同期処理を行う、jQueryの$.ajaxメソッドは、返り値がDeferredオブジェクトです。
そのため、新たにDeferredオブジェクトを作らなくても、そのままthen()(またはdone()、fail()、when())でつなげて処理を書くことができます。

$.ajax以外にも、$.get()や$.post()も同様にDeferredオブジェクトを返すので、then()などをつなげて書くことができます。


以上、jQuery.Deferredを使った書き方を解説いたしました。
これを使いこなせれば、複雑なアニメーションやAjaxも、コールバック地獄に陥らず、雰囲気よく書けそうです。

あなたのビジネスのWeb戦略を、ぜひキタックにおまかせください。

効果を出すためのサイト運営、集客できるウェブ広告

ブログの更新情報をお知らせしています。