Deferredのthen、done、failでハマったこと(jQuery)
本記事では、jQueryのDeferredを使用する際、
then、done、failでハマったことを紹介していきます。
本記事の内容です。
Deferredって何?
本記事で説明すると長くなってしまうので、下記のページを参照してください。
簡単に説明しますと、「非同期処理を良い感じに行う仕組み」です。
techblog.yahoo.co.jp
qiita.com
何でハマったのか?
以下のコードで処理が思った順番に実行されない。doneHogeとfailHogeが両方、一気に実行されてしまう。
$(function() { $('#button').click(function() { $.get({ url: '何かしらのurl' }).done(doneHoge()).fail(failHoge()); }); function doneHoge(data, textStatus, jqXHR) { alert('Done!'); } function failHoge() { alert('Fail...'); } });
何が駄目だったのか?
then、done、failは、あくまでも引数の関数を登録するだけなので、引数で渡す時に"()"を付けてしまうと、
渡している関数が即時実行され登録されない。
上記から、関数の後ろに"()"を付けずに、引数で渡さなければいけない。
修正後のコード
修正コード1は、関数を即時実行させずに情報を渡し登録させるパターン。修正コード1
$(function() { $('#button').click(function() { $.get({ url: '何かしらのurl' }).done(doneHoge).fail(failHoge); }); function doneHoge(data, textStatus, jqXHR) { alert('Done!'); } function failHoge() { alert('Fail...'); } });
修正コード2は、関数を即時実行するが、
即時実行した関数から登録する関数を返してあげるパターン。
こちらはコードが長くなるが、細かいことが行える。
修正コード2
$(function() { $('#button').click(function() { // $.get({ // url: '何かしらのurl' // }).done(doneHoge).fail(failHoge); hoge().done(doneHoge()).fail(failHoge()); }); function hoge() { var defer = $.Deferred(); // なにかしらの処理を行う if (/* 何かしらの条件 */) { // 呼び出し元に処理が成功したと伝える defer.resolve(); } else { // 呼び出し元に処理が失敗したと伝える defer.reject(); } // promiseを作って返す return defer.promise(); } function doneHoge(defer) { return function (data, textStatus, jqXHR) { alert('Done!'); } } function failHoge(defer) { return function () { alert('Fail...'); } } });
最後に
コードではthenについて触れませんでしたが、thenもdoneおよびfailと同じです。