C#開発者のための最新JavaScript事情(Promise編パート2):特集:C#×JavaScript(2/3 ページ)
今回はPromiseオブジェクトの状態と、Promiseオブジェクトが提供するメソッド、thenableオブジェクトなど、少し高度な話題について見てみよう。
Promise.raceメソッド
前回見たPromise.allオブジェクトは、「配列などに格納した複数のPromiseオブジェクトの全てが完了すること」を表すPromiseオブジェクトを返す。全てのプロミスが完了するのを待機し、それぞれの完了結果を配列の要素として取り扱える。
Promise.raceメソッドも配列などに格納された複数のPromiseオブジェクトを受け取り、新たなPromiseオブジェクトを返すが、Promise.allメソッドとは異なり、複数のPromiseオブジェクトのいずれかが完了した時点で、新たなPromiseオブジェクトも完了する。
以下に例を示す。
var promiselist = [
new Promise(
(resolve, reject) => setTimeout(() => resolve("promise0"), 500)
),
new Promise(
(resolve, reject) => setTimeout(() => resolve("promise1"), 100)
),
new Promise(
(resolve, reject) => setTimeout(() => resolve("promise2"), 1000)
)
];
Promise.race(promiselist).then(
value => console.log("resolve: " + value),
reason => console.log("reject: " + reason)
);
ここでは三つのPromiseオブジェクトを要素とする配列を作成して、それをPromise.raceメソッドに渡している。要素となるPromiseオブジェクトではsetTimeout関数を使って、それぞれのプロミスが完了するタイミングに差を付けている。
このコードを実行すると次のようになる。
>node --harmony promisetest.js
resolve: promise1
なお、上の実行結果では分からないのだが、プロンプトが表示されて、コンソールへの入力が可能になるまでには少し時間がかかる。これはPromise.raceメソッドが返すPromiseオブジェクトは完了しても、もともとの配列に格納されていたPromiseオブジェクトの実行は続けられるためだ。上のコードを少し変更して試してみると、このことが分かる。
var promiselist = [
new Promise(
(resolve, reject) => setTimeout(() => {
console.log("promise0");
resolve("promise0");
}, 500)
),
…… 省略 ……
];
Promise.race(promiselist).then(
value => console.log("resolve: " + value),
reason => console.log("reject: " + reason)
);
ここでは最初の要素が完了したときに、コンソールに出力するように変更している。このコードの実行結果は次のようになる。
>node --harmony promisetest.js
resolve: promise1
promise0
このように、最初に実行が完了しなかったPromiseオブジェクトについても、その完了時にコンソールにメッセージを表示している。
余談ではあるが、Promise.allメソッドに渡した複数のPromiseオブジェクトのいずれかが失敗したときにはどうなるだろう。上のコードを再度改変して、少し試してみよう。
var promiselist = [
new Promise(
(resolve, reject) => setTimeout(() => reject("promise0"), 500)
),
…… 省略 ……
];
Promise.all(promiselist).then(
value => console.log("resolve: " + value),
reason => console.log("reject: " + reason)
);
ここでは最初の要素でタイムアウト発生後にreject関数を呼び出している(失敗)。この場合、実行結果は次のようになる。比較のため、全てのPromiseオブジェクトが成功して完了した場合の出力結果も示しておこう。
※失敗した場合
>node --harmony promisetest.js
reject: promise0
※全て成功した場合
>node --harmony promisetest.js
resolve: promise0,promise1,promise2
前回は述べなかったが、この結果から分かる通り、Promise.allメソッドが返すPromiseオブジェクトは、それが待機するPromiseオブジェクトのいずれかが失敗して完了した場合には、その時点で完了する(そのため、失敗時には「promise0」のみが表示されている。これは成功時の「promise0,promise1,promise2」とは異なる結果だ)。
では、本稿の最後に「thenable」(then可能な)オブジェクトについて見てみよう。
Copyright© Digital Advantage Corp. All Rights Reserved.