JavaScriptにおけるプロミスの紹介
コールバックモデルによる非同期処理は、コールバックヘルという状況を簡単に引き起こすことは既にご存知でしょう。そのため、JavaScriptにはプロミス(promise)と呼ばれる新しいモデルが導入されました。このモデルを学んでいきましょう。
プロミスはオブジェクトであり、そのパラメータとして関数が渡され、その内部に非同期コードを記述します:
let promise = new Promise(function() {
// 非同期コード
});
ご覧のように、プロミスオブジェクトをpromiseという変数に代入しました。コードの別の場所では、この変数に対してthenメソッドを適用し、このプロミスの作成時に記述した非同期コードが完了した際に実行されるべきコードを含む関数を渡すことができます:
promise.then(function() {
// 非同期コードの完了時に実行される
});
少々複雑に聞こえるかもしれませんので、例を見てみましょう。次のような非同期コードがあるとします:
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
ここで、非同期処理における主な課題、つまりタイマー発火後に何らかのコードを実行したいとします。そのコードをタイマー内に配置したくなく、また、変数resultに記述した結果を何らかの形でそのコードに渡したいとします。これは、前のレッスンでコールバックやサブスクリプションを通して解決した課題です。では、プロミスを使ってこれをどのように行うか見てみましょう。
まず、非同期コードをプロミスでラップする必要があります:
let promise = new Promise(function() {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
しかし、これだけでは不十分です。非同期コードが完了したことを明示的に示す必要があります。これには、特別な完了関数が役立ちます。この関数は、指定されていれば、関数の最初のパラメータとして自動的に渡されます:
let promise = new Promise(function(resolve) { // パラメータを指定
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
完了関数を使用することで、プロミスに対して非同期コードが完了したことを明示的に示すことができます。これを行うには、適切な場所でこの関数を呼び出します:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(); // プロミスを完了させる
}, 3000);
});
また、非同期コードの結果を外部に渡したい場合は、その結果を完了関数のパラメータとして渡すことができます:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(result); // 結果を渡す
}, 3000);
});
もちろん、中間変数を省略することもできます:
let promise = new Promise(function(resolve) {
setTimeout(function() {
resolve([1, 2, 3, 4, 5]);
}, 3000);
});
これで、他のどの場所からでもプロミスのthenメソッドを呼び出すことができます:
promise.then(function() {
// プロミスの完了時に実行される
});
プロミスの結果は、指定すれば関数の最初のパラメータとして渡されます:
promise.then(function(result) {
console.log(result); // 結果の配列を出力
});
5秒の遅延を持つプロミスを作成してください。遅延後、プロミスは何らかのテキストを結果として返して完了するようにします。そのテキストを画面に表示してください。