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

jQueryのDeferredの基本的な使い方メモ

More than 1 year has passed since last update.

すぐわからなくなるので基本的なところだけメモ。

async(function() {
    console.log('async');
});
console.log('hoge');

/**指定した関数を 1 秒後に実行する*/
function async(f) {
    setTimeout(f, 1000);
}

これを実行すると、

実行結果
hoge
async

とコンソールに出力される。

しかし、どうしても非同期処理の後で hoge を出力させたい場合に Deferred を使う。

var d = new $.Deferred();

async(function() {
    console.log('async');
    d.resolve();
});

d.promise().then(function() {
    console.log('hoge');
});

/**指定した関数を 1 秒後に実行する*/
function async(f) {
    setTimeout(f, 1000);
}
実行結果
async
hoge
  • new $.Deferred()Deferred のオブジェクトを生成する。
  • 非同期処理が完了した時点で、生成しておいた Deferred オブジェクトの resolve() メソッドを実行する。
  • Deferred オブジェクトの promise() メソッドを実行し、その戻り値(promise オブジェクト)の then() メソッドに非同期処理の後に実行したい処理を渡す。

then() はメソッドチェーンができるので、

var d = new $.Deferred();

async(function() {
    console.log('async');
    d.resolve();
});

d.promise()
.then(function() {
    console.log('hoge');
})
.then(function() {
    console.log('fuga');
});

/**指定した関数を 1 秒後に実行する*/
function async(f) {
    setTimeout(f, 1000);
}

という風に書ける。

実行結果
async
hoge
fuga

ただし、このままだと2つ目の then() は1つ目の then() が終了するとすぐ実行される。

なので、

var d = new $.Deferred();

async(function() {
    console.log('async');
    d.resolve();
});

d.promise()
.then(function() {
    // ★1つ目の then() が非同期処理
    async(function() {
       console.log('hoge'); 
    });
})
.then(function() {
    console.log('fuga');
});

/**指定した関数を 1 秒後に実行する*/
function async(f) {
    setTimeout(f, 1000);
}

こんな実装になっていると、

実行結果
async
fuga
hoge

となる。

1つ目の then() の非同期処理が終わってから2つ目の then() を実行したい場合は、1つ目の then() で新しい promise オブジェクトを返す。

var d = new $.Deferred();

async(function() {
    console.log('async');
    d.resolve();
});

d.promise()
.then(function() {
    var d2 = new $.Deferred();

    async(function() {
        console.log('hoge');
        d2.resolve();
    });

    return d2.promise();
})
.then(function() {
    console.log('fuga');
});

/**指定した関数を 1 秒後に実行する*/
function async(f) {
    setTimeout(f, 1000);
}
実行結果
async
hoge
fuga

参考

opengl-8080
ただのSE。Java好き。
tis
創業40年超のSIerです。
https://www.tis.co.jp/
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
ユーザーは見つかりませんでした