Help us understand the problem. What is going on with this article?

JQuery.Deferredでwait風メソッド

More than 1 year has passed since last update.

javascriptで実行待ちの場合、setTimeout使えばいいんですがいちいちコールバック関数として引き渡してやる必要があるのでたとえば2秒待った後に1秒待つ、といったように実装する際、コールバックがネストし、見ていてやるせないコードになります。
(そんな設計するのがそもそも悪いってのもあるかもしれませんが)
例えばこんな感じ。

setTimeout(function(){
    // 2000ms 待った後に実行されるコールバック
    setTimeout(function(){
      // 1000ms 待った後に実行されるコールバック
      // その何秒後かにまた実行するコードを書くとさらにネストが下がっていく...
    },1000);
},2000);

ネストが2個とかそこらならまだ許容範囲かもしれませんが、
どうせならJQuery.Deferredを使ってネストをあまり下げないように書いてしまいましょう。

まずは以下のようなメソッドを定義しておきます。

$.wait = function(msec) {
    // Deferredのインスタンスを作成
    var d = new $.Deferred;

    setTimeout(function(){
        // 指定時間経過後にresolveしてdeferredを解決する
        d.resolve(msec);
    }, msec);

    return d.promise();
};

見ての通り、別にむずかしいことはやってません。
引数のチェック等は必要であれば適宜入れておくといいと思います。

使い方は下記のような感じです。

$.wait(2000)
  .done(function(){
      console.log("2000ミリ秒待ちました");
  });

doneでコールバックを登録することで指定した時間経過後に実行するメソッドを定義できます。
また最初にあげたような多段の場合ですが、こちらはthenで指定して中で再度waitをコールし、返ってきたdeferredをreturnしてやれば次のチェーンに引き渡せます。

具体的には以下のような感じです。

$.wait(2000)
  .then(function(ms){
      console.log(ms + "ミリ秒待ちました");
      // 次のコールバックに渡すために新たなdeferredを返却
      return $.wait(1000); 
      // 次のコールバックも同様のやり方でつなげばいくらつないでもネストはこれ以上下がらない
  })
  .done(function(ms){
      console.log(ms + "ミリ秒待ちました");
  });

これでまず2000ms待ってから、コンソールに表示し、さらに1000ms待ってからコンソールに表示、といったような動きをします。
thenの中でwaitのdeferredをreturnというのを繰り返すことでネストを深くせずにチェーンを連続して書けます。
ちなみにwaitの中でresolveする時にwaitの引数をそのまま渡しているのでコールバックの中でそれを引数として受け取れます。

jQuery.deferredについて更に知りたい方は下記を参照ください。
https://www.null-engineer.ml/

ki-sato
インテリジェンスのかけらもないプログラマー
https://www.null-engineer.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした