HTML 5.1で追加されたHTMLフォームの検証メソッドとPromise関連の新機能:特集:HTML 5.1概説(2/3 ページ)
HTML 5.1で追加された新機能のうち、フォームの検証に使用できるreportValidityメソッドと、Promiseオブジェクトに関連した新機能を紹介する。
EnqueueJob/NextJobメソッド
「Changes」ページには、HTML 5.1での変更点が幾つか挙げられているが、このうち「<picture>要素とsrcset属性」「requestAnimationFrame API」については前回の記事で、「<details>要素と<summary>要素」「コンテキストメニュー」については「Dev Basics/Keyword HTML 5.1」で触れている。そこで次に「EnqueueJobとNextJob」について簡単に見てみよう。
「enqueueJob and nextJob help explain Promise resolution in terms of microtasks」(マイクロタスクの観点からPromiseがどう解決されるのかを説明するのに役立つ)といわれてもなかなか分かりにくいのだが、これはHTML 5.1仕様とECMAScript仕様の齟齬を回避するための「willfull violation」(故意のJavaScript仕様違反)であり、主にブラウザ開発者に向けた変更点だと考えられる。
つまり、現状のECMAScript仕様では、Promise関連の処理をWebブラウザで処理するのが難しいため、HTML 5.1の仕様ではECMAScript仕様を上書きしているということになる(ここではHTML 5.1でEnqueueJob/NextJobメソッドを定義し、ECMAScriptのそれらを上書きすることで、ブラウザ内でPromiseを素直に処理できるようにしていると筆者は読み取った)。
実際、HTML 5.1の言語仕様の「7.1.3.7 ntegration with the JavaScript job queue」を見ると「Promiseの処理をJavaScriptの実行コンテキストスタックで何らかの順序で行うことに関して、一定の規則を示すために、JavaScriptの言語仕様ではJavaScriptのジョブとそのキューを抽象化したものを定義しているが、HTML 5.1の言語仕様の執筆時点では、JavaScriptのホスト環境としてHTMLを統合することを考えると、この仕様には柔軟性が足りていない」といったことが記述されている(筆者による意訳)。
そして、EnqueueJobに関して、ユーザーエージェント(Webブラウザ)はECMAScriptの言語仕様ではなく、HTML 5.1の仕様に従わなければならず、これによりPromiseを処理するためのジョブをWebブラウザが保持するイベントループにキューイングして、適切に処理できるようになるとのことだ。
うまくいかない場合を試してみるのは難しいことから、実際にChrome/Firefox/Edgeで動作するコードを書いてみた。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HTML 5.1 Promise sample</title>
<script>
const a = [
{ n: 1, amount: 3000 },
{ n: 2, amount: 2000 },
{ n: 3, amount: 4000 },
{ n: 4, amount: 1000 }
];
function sleepAsync(item) {
return new Promise(
function(resolve, reject) {
window.setTimeout(function() {
document.getElementById("output" + item.n).innerText = "resolved";
resolve("resolved");
}, item.amount)
}
)
}
window.onload = function() {
const plist = a.map(sleepAsync);
Promise.all(plist).then(
function(msg) {
document.getElementById("outputall").innerText = msg;
}
);
}
</script>
</head>
<body>
<ol>
<li> <p id="output1">start processing Promise.</p></li>
<li> <p id="output2">start processing Promise.</p></li>
<li> <p id="output3">start processing Promise.</p></li>
<li> <p id="output4">start processing Promise.</p></li>
</ol>
<div><b>all promises status:</b> <span id="outputall"></span></div>
</body>
</html>
詳細な解説は割愛するが、上のコードでは4つのPromiseオブジェクトを作成している。これらのオブジェクトは1000ミリ秒、2000ミリ秒、3000ミリ秒、4000ミリ秒を待機した後で、自身に関連付けられている箇条書きの要素(idが「output」+「1〜4の番号」の<li>要素)に「resolved」と書き込むものだ。そして、4つのPromiseオブジェクトをまとめたもう1つのPromiseオブジェクトを「Promise.all」メソッドで作成し、全ての処理が完了したら、「all promises status」行に処理結果を表示するようになっている。
実行途中の様子を以下に示す。
このようなPromise処理をブラウザ内でも実行可能とするために、HTML 5.1では「あえてJavaScriptの言語仕様を上書き」しているということだ。
なお、上で見た「willfull violation」という語についてはHTML 5.1の言語仕様の「1.5.2 Compliance with other specifications」で「HTML 5.1の言語仕様は、それ以外のさまざまな仕様と関連するが、残念ながら他の仕様とは矛盾する必要性が生じたときには、それらの仕様で定められている要件に違反することがある。違反がある部分については個々に『willfull violation』であることと、違反した理由が示される」(筆者による意訳)とある。EnqueueJob/NextJobはそうした「故意の違反」の1つである。
なお、IE11では基本的には上記コードは実行できない。これはPromiseオブジェクトをIE11がサポートしていないからだ。
ただし、Promise.jsで配布されているpolyfillを読み込むことで実行可能だ(詳細は割愛)。
次に、HTML 5.1で追加されたもう1つのPromise関連の新機能を見てみよう。
Copyright© Digital Advantage Corp. All Rights Reserved.