今回はPromiseオブジェクトの状態と、Promiseオブジェクトが提供するメソッド、thenableオブジェクトなど、少し高度な話題について見てみよう。
powered by Insider.NET
前回はPromiseオブジェクトを使用した非同期処理の基本について見た。今回はPromiseオブジェクトについてさらに詳しく見ていこう。
Promiseオブジェクトは次の三つの状態を持つ。
fulfilledとrejectedは、Promiseオブジェクトが表す非同期処理が完了しており、fulfilledはそれが成功したことを、rejectedは失敗したことを表す。pendingは非同期処理がまだ完了していないことを表す。これらは相互に排他的であり、かつ一度fulfilled状態あるいはrejected状態になったPromiseオブジェクトの状態がそれ以外に遷移することはない。
これを図に示すと次のようになる。
また、pending以外の状態(fulfilledあるいはrejectedのいずれかの状態)のことを「settled」(=fulfilledかsettledのいずれかに落ち着いて変化することがない状態)と呼ぶことがある。
fulfilled状態のPromiseオブジェクトに対してthenメソッドを呼び出すと、第1引数に指定した関数(=成功時に実行される関数)が呼び出される。rejected状態の場合は、第2引数に指定した関数(=失敗時に実行される関数)が呼び出される。pending状態の場合は、他の二つの状態のいずれかに状態が変化したときに実行される関数のセットアップが行われる。
// new Promise()呼び出しで作成した直後のプロミスはpending状態
var p = new Promise((resolve, reject) => { ... });
…… 省略 ……
p.then(
function(value) { ... }, // pがfulfilled状態の場合に呼び出される
function(reason) { ... } // pがrejected状態の場合に呼び出される
);
最後にPromiseオブジェクトがfulfilled状態かrejected状態のいずれかになるか、プロミスチェーンによって別のPromiseオブジェクトの状態と関連付けられることを「resolved」(解決された)と呼ぶことがある。
コンストラクタ呼び出しによって作成された直後のPromiseオブジェクトはpending状態になるが、最初からfulfilled/rejected状態のPromiseオブジェクトを作成するメソッドもある。それが次に見るPromise.resolveメソッドとPromise.rejectメソッドだ。
Promise.resolveメソッドは、引数に渡した値を完了値として成功した状態のPromiseオブジェクトを返す(引数にPromiseオブジェクトを渡した場合は、そのPromiseオブジェクトが戻り値となる)。これはつまり、以下のPromiseコンストラクタ呼び出しと同じことを意味する。
// 以下の二つのコンストラクタ/メソッド呼び出しは同じ意味
var p1 = new Promise((resolve, reject) => resolve("always resolved"));
var p2 = Promise.resolve("always resolved");
// p1とp2は成功しているので常に第1引数(=resolve関数)が呼び出される
p1.then(
function(value) { console.log("success: " + value); },
function(reason) { console.log("fail: " + reason); }
);
p2.then(
value => console.log("success: " + value),
reason => console.log("fail: " + reason)
);
これは何かのオブジェクトをPromiseオブジェクト化して、それを使って何らかの処理を行いたいときに活用できる(後述)。
Promise.rejectメソッドは、引数に渡した値を非同期処理が失敗した理由とするPromiseオブジェクトを返す。Promise.resolveメソッドと対称的に、こちらは以下のコンストラクタ呼び出しと同じことを意味する。
// 以下の二つのコンストラクタ/メソッド呼び出しは同じ意味
var p1 = new Promise((resolve, reject) => reject("always rejected"));
var p2 = Promise.reject("always rejected");
// p1とp2は失敗しているので常に第2引数(=reject関数)が呼び出される
p1.then(
function(value) { console.log("success: " + value); },
function(reason) { console.log("fail: " + reason); }
);
p2.then(
value => console.log("success: " + value),
reason => console.log("fail: " + reason)
);
常に失敗した(rejected状態の)Promiseオブジェクトが戻り値となるので、通常時にはあまり使い道はないだろうが、テスト/デバッグ用途で使えると思われる。
次に前回説明したPromise.allメソッドと対になるPromise.raceメソッドについて簡単に見ておこう。
Copyright© Digital Advantage Corp. All Rights Reserved.