HTML 5.1ではPromiseに関連して追加された機能が他にもある。それがonrejectionhandledイベントとonunhandledrejectionイベントの2つのイベントだ。前者はPromiseが表す操作の失敗がreject関数で処理された場合に、後者は処理されなかった場合に発生する。
これら2つのイベントを利用するサンプルコードを以下に示す。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>rejected Promise event sample</title>
<script>
function generateHandled() {
var p = Promise.reject("rejected and handled");
setTimeout(function() {
p.then(
v => console.log(v),
e => console.log(e) // 失敗した(rejectされた)Promiseを処理
);
});
}
function generateUnhandled() {
// 失敗したPromiseを放り投げたまま
var p = Promise.reject("rejected and unhandled");
}
// 失敗したPromiseがreject関数で処理されたときに呼び出される
window.addEventListener("rejectionhandled", function(e) {
console.log("in rejectionhandler");
console.log(e.reason);
});
// 失敗したPromiseが処理されなかったときに呼び出される
window.addEventListener("unhandledrejection", function(e) {
console.log("in unhandledrejectionhandler");
console.log(e.reason);
});
</script>
</head>
<body>
<button onclick="generateHandled()">Handle it!</button>
<button onclick="generateUnhandled()">Unhandle it!</button>
</body>
</html>
このHTMLコードではボタンを2つ用意して、その両者でPromise.rejectメソッドにより、失敗したPromiseオブジェクトを作成している。そして、一方ではそれをreject関数(p.thenメソッド呼び出しの第2引数、ここでは「e => console.log(e)」というアロー関数)で処理している(generateHandled関数)。もう一方では生成しっぱなしで何も処理をしていない(generateUnhandled関数)。
そして、「window.addEventListener」メソッドで2つのイベントハンドラーを登録している。それぞれのハンドラーでは自身のハンドラー名と、Promiseオブジェクトが失敗した原因(e.reason)をコンソールに出力するようにしている。
これを実行した結果を以下に示す。まずは[Handle it!]ボタンをクリックして、失敗したPromiseオブジェクトをreject関数で処理した場合だ。
上の画像を見ると分かるように、Promise.rejectメソッドで失敗したPromiseオブジェクトが作成された時点で「unhandledrejectionhandler」ハンドラーが呼び出されている(コンソール出力の最初の3行。これはrejecthandler.htmlファイルの8行目=Promise.rejectメソッド呼び出しで「処理されていないPromiseオブジェクト」が生成されたということだ)。コンソール出力の4行目を見ると、12行目の「e => console.log(e)」でこれが処理されたことが分かる。最後に、失敗したPromiseオブジェクトが処理されたことから、rejectionhandledhandler関数が呼び出されて、2行分(ハンドラー名+失敗の原因)の出力が行われている。
なお、こちらの処理ではsetTimeout関数で処理を遅延させているが、これはPromiseオブジェクトによる何らかの非同期処理で時間がかかっていることのエミュレーションである(このサンプルでは、setTimeout関数呼び出しがないとイベントハンドラーが呼び出されないことに注意)。
失敗したPromiseオブジェクトを処理しない場合は次のようになる。
こちらは先ほどのrejectionhandledイベントの処理冒頭部分で見られたのと同様に、Promise.rejectメソッド呼び出し(rejecthandler.htmlファイルの17行目)で未処理のPromiseオブジェクトが生成され、それによって、unhandledrejectionイベントハンドラーが呼び出されて、計3行の出力が行われている。
Promiseオブジェクトは何らかの非同期処理を実行するものだが、最終的にそれが失敗した場合に、それが処理されたか、あるいは処理されないままかによって、状況に応じた処理を行うためにこれら2つのイベントが使えるだろう。例えば、非同期処理に失敗したPromiseオブジェクトが処理されていない場合には、ユーザーに対して、何らかの通知を行い、処理を再実行するかどうかを問い合わせるといった対処が考えられる。
なお、2017年2月9日時点では、これら2つのイベントはChromeでは実装されているが、FirefoxとEdgeには実装されていないので、使うには注意が必要だ。
今回はHTMLフォームに対して検証を行うreportValidityメソッドと、Promiseに関連する2つの新機能について見た。次回以降も、コード例とともにHTML 5.1の新機能を紹介していく予定だ。
Copyright© Digital Advantage Corp. All Rights Reserved.