Deferredオブジェクトを理解する
jQueryのDeferredオブジェクトの基本概念、非同期処理の表現方法、およびその状態(pending、resolved、rejected)を理解します。
「Deferredオブジェクトを理解する」はCoddyKit上の無料jQuery Academyレッスンです。 これはレッスン1/3です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはjQuery Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 jQuery Academyコースには全3レッスンが含まれています。
非同期処理とコールバック
Web開発では、多くの処理がすぐに完了するとは限りません。サーバーからデータを取得したり、ユーザーのクリックを待ったりする処理を考えてみてください。これらが非同期処理です。
従来はコールバック、つまり非同期処理が完了した後にだけ実行される関数を使用していました。しかし、コールバックを入れ子にすると「コールバック地獄」に陥り、コードの読み取りや保守が難しくなることがあります。
jQuery Deferredの概要
このような場合に役立つのが、jQueryのDeferredオブジェクトです。Deferredオブジェクトを使うと、非同期処理をより整理された形で管理できます。
Deferredオブジェクトは、将来得られる結果のプレースホルダーのように機能します。処理が成功した場合でも失敗した場合でも、処理の完了時に実行する関数を登録できます。メインのコードをブロックすることもありません。
Deferredの3つの状態
Deferredオブジェクトは、それが表す非同期処理の状態に応じて、次の3つの状態のいずれかになります。
- Pending: 初期状態です。処理はまだ完了していません。
- Resolved: 処理が正常に完了した状態です。
- Rejected: 処理に失敗したか、エラーが発生した状態です。
一度resolvedまたはrejectedになると、Deferredオブジェクトの状態は再び変更できません。
Deferredオブジェクトを作成
$.Deferred()を使って新しいDeferredオブジェクトを作成します。このオブジェクトはpending状態で開始します。
状態を変更するメソッドと、状態が変更されたときに実行するコールバック関数を登録するメソッドが用意されています。
作成してみましょう。
var myDeferred = $.Deferred();
console.log('Deferred is pending: ' + (myDeferred.state() === 'pending'));成功を通知:.resolve()
非同期処理が正常に完了したら、Deferredオブジェクトの.resolve()メソッドを呼び出します。
これにより、状態がpendingからresolvedに変わります。.resolve()に渡した引数は、成功時のコールバックに渡されます。
状態の変化を確認してみましょう。
var myDeferred = $.Deferred();
console.log('Initial state: ' + myDeferred.state());
setTimeout(function() {
myDeferred.resolve('Data fetched!');
console.log('New state: ' + myDeferred.state());
}, 1000);失敗を通知:.reject()
非同期処理に失敗した場合は、.reject()メソッドを呼び出します。
これにより、Deferredの状態がpendingからrejectedに変わります。.reject()に渡した引数は失敗時のコールバックに渡され、エラーメッセージなどに使われます。
rejectionの動作を確認してみましょう。
var myDeferred = $.Deferred();
console.log('Initial state: ' + myDeferred.state());
setTimeout(function() {
myDeferred.reject('Network error!');
console.log('New state: ' + myDeferred.state());
}, 1000);成功を処理:.done()
処理が成功した場合(Deferredがresolvedの場合)に反応するには、.done()メソッドを使ってコールバック関数を登録します。
この関数は.resolve()が呼び出された場合にのみ実行され、.resolve()から渡された引数を受け取ります。
データを処理してみましょう。
var fetchData = function() {
var dfd = $.Deferred();
setTimeout(function() {
var success = true; // Simulate success
if (success) {
dfd.resolve('User data loaded.');
} else {
dfd.reject('Failed to load user data.');
}
}, 1000);
return dfd;
};
fetchData().done(function(message) {
console.log('Success handler: ' + message);
});失敗を処理:.fail()
同様に、エラーを処理する場合(Deferredがrejectedの場合)は、.fail()メソッドを使用します。
.fail()に渡したコールバック関数は、.reject()が呼び出された場合にのみ実行され、その引数を受け取ります。
エラーをシミュレートしてみましょう。
var fetchData = function() {
var dfd = $.Deferred();
setTimeout(function() {
var success = false; // Simulate failure
if (success) {
dfd.resolve('User data loaded.');
} else {
dfd.reject('Failed to load user data.');
}
}, 1000);
return dfd;
};
fetchData().fail(function(errorMessage) {
console.log('Error handler: ' + errorMessage);
});常に実行:.always()
非同期処理が成功したか失敗したかにかかわらず、実行する必要があるコードもあります。そのような場合に使用するのが.always()です。
.always()で登録したコールバック関数は、Deferredがresolvedの場合でもrejectedの場合でも実行されます。
後片付けやUIの最終更新には.always()を使用します。
var fetchData = function(shouldSucceed) {
var dfd = $.Deferred();
setTimeout(function() {
if (shouldSucceed) {
dfd.resolve('Data received!');
} else {
dfd.reject('Request failed!');
}
}, 1000);
return dfd;
};
fetchData(false)
.done(function(msg) { console.log('Success: ' + msg); })
.fail(function(err) { console.log('Failure: ' + err); })
.always(function() { console.log('Operation finished.'); });.promise()で保護
関数からDeferredオブジェクトを返す場合、外部のコードから状態を変更できないようにしたいことがあります(たとえば、.resolve()や.reject()を直接呼び出せないようにする場合です)。
.promise()メソッドは、Deferredオブジェクトの「読み取り専用」バージョンを返します。コールバックを登録するメソッド(.done()、.fail()、.always()など)のみを公開し、状態を変更するメソッドは公開しません。
var createAsyncTask = function() {
var dfd = $.Deferred();
setTimeout(function() {
dfd.resolve('Task done!');
}, 500);
// Return only the promise, not the full Deferred object
return dfd.promise();
};
var taskPromise = createAsyncTask();
taskPromise.done(function(msg) {
console.log(msg);
});
// The following would throw an error or do nothing if trying to resolve/reject a promise
// taskPromise.resolve('Attempted to resolve externally'); // This is not possible on a promise object知識を確認しましょう
Deferredオブジェクトが非同期処理を正常に完了した場合にのみ実行されるコールバックを登録するには、次のメソッドのうちどれを使用しますか?
振り返り:Deferredの基礎
よくできました!このレッスンでは、jQueryのDeferredオブジェクトに関する基本概念を理解できました。
- 非同期処理を管理し、コールバック地獄を避けられます。
- pending、resolved、rejectedのいずれかの状態になります。
- 成功には
.resolve()、失敗には.reject()を使用します。 - コールバックは、成功時の
.done()、失敗時の.fail()、両方に対応する.always()で登録します。 .promise()は、状態の操作を保護する読み取り専用オブジェクトを返します。
次は、これらの強力なオブジェクトをチェーンや組み合わせで扱う方法を学びます。
よくある質問
「Deferredオブジェクトを理解する」レッスンは無料ですか?
はい。「Deferredオブジェクトを理解する」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、jQuery Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 jQuery Academyコースには全3レッスンが含まれています。
「Deferredオブジェクトを理解する」で何を学びますか?
jQueryのDeferredオブジェクトの基本概念、非同期処理の表現方法、およびその状態(pending、resolved、rejected)を理解します。 ブラウザで直接実行するハンズオンコードでjQuery Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
jQuery Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのjQuery Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/3です。
「Deferredオブジェクトを理解する」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このjQuery Academyレッスンでコードを書いて実行できますか?
はい。すべてのjQuery Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Deferredオブジェクトを理解する
- Promiseの連結と合成
- 複数の非同期タスクの処理