diff options
author | Masahiro FUJIMOTO <mfujimot@gmail.com> | 2021-09-07 22:56:20 +0900 |
---|---|---|
committer | Masahiro FUJIMOTO <mfujimot@gmail.com> | 2021-09-07 22:56:20 +0900 |
commit | db091658bee048cac6a43ab7fe346ea7d420818a (patch) | |
tree | f551c4caac755cf43c99a5dccab68da21bf16765 /files/ja/web/javascript/reference/global_objects | |
parent | fe6f6abf2b7c497bf1f97f73a82dde7cf48eb79f (diff) | |
parent | 33a5bcbcd367750dc0b7376f692d5aacfb799303 (diff) | |
download | translated-content-db091658bee048cac6a43ab7fe346ea7d420818a.tar.gz translated-content-db091658bee048cac6a43ab7fe346ea7d420818a.tar.bz2 translated-content-db091658bee048cac6a43ab7fe346ea7d420818a.zip |
Merge branch 'main' into 20210818-Glossary/Type
Diffstat (limited to 'files/ja/web/javascript/reference/global_objects')
10 files changed, 719 insertions, 688 deletions
diff --git a/files/ja/web/javascript/reference/global_objects/escape/index.html b/files/ja/web/javascript/reference/global_objects/escape/index.html deleted file mode 100644 index 046fd2667b..0000000000 --- a/files/ja/web/javascript/reference/global_objects/escape/index.html +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: escape() -slug: Web/JavaScript/Reference/Global_Objects/escape -tags: - - Deprecated - - JavaScript - - Method - - メソッド - - 非推奨 -translation_of: Web/JavaScript/Reference/Global_Objects/escape ---- -<div>{{jsSidebar("Objects")}}</div> - -<div class="warning"><strong>警告:</strong> <code>escape()</code> は厳密には非推奨ではありませんが (「ウェブ標準から削除された」という意味で)、ECMA-262 標準の <a href="https://www.ecma-international.org/ecma-262/9.0/index.html#sec-additional-ecmascript-features-for-web-browsers">Annex B</a> で定義されており、その導入部には次のように書かれています。 - -<blockquote>… この付属書で規定されているすべての言語機能と動作は、1つ以上の望ましくない特性を持ち、レガシーな使用例がない場合は、この仕様から削除されます。…<br> -… プログラマは、新しい ECMAScript コードを書くときに、これらの機能や動作の存在を使用したり、仮定したりしてはいけません。…</blockquote> -</div> - -<p><span class="seoSummary">The <code><strong>escape()</strong></code> 関数は、特定の文字を16進数のエスケープシーケンスで置き換えた新しい文字列を計算します。</span></p> - -<div class="blockIndicator note"> -<p><strong>メモ:</strong> この関数は、主に URL クエリ (URL の <code>?</code> に続く部分) に使われていました。 — "<code>\x<var>HH</var></code>" の形式を使用して、ふつうの文字列リテラルをエスケープするためのものでは<em>ありません</em>。 (HHは2桁の16進数であり、より高い面の Unicode 文字には「\xHH\xHHxHH」という形式が使われます。)</p> - -<p>文字列リテラル内のエスケープされた文字は、 <code>\x</code> を <code>%</code> に置き換えてから、 <code>decodeURIComponent()</code> 関数を使用することで展開することができます。</p> -</div> - -<h2 id="Syntax" name="Syntax">構文</h2> - -<pre class="syntaxbox">escape(<var>str</var>)</pre> - -<h3 id="Parameters" name="Parameters">引数</h3> - -<dl> - <dt><code><var>str</var></code></dt> - <dd>エンコードする文字列。</dd> -</dl> - -<h3 id="Return_value" name="Return_value">返値</h3> - -<p>特定の文字がエスケープされた新しい文字列。</p> - -<h2 id="Description" name="Description">解説</h2> - -<p><code>escape</code> 関数は<em>グローバルオブジェクト</em>のプロパティです。特殊文字は <code>@*_+-./</code> 以外の文字が符号化されます。</p> - -<p>文字の16進数形式として、文字コードの値が <code>0xFF</code> 以下になる文字は 2 桁のエスケープシーケンス <code>%<var>xx</var></code> が、それ以上の場合は 4 桁のエスケープシーケンス <code>%<strong>u</strong><var>xxxx</var></code><code>%<strong>u</strong><var>xxxx</var></code> が使われます。</p> - -<h2 id="Examples" name="Examples">例</h2> - -<pre class="brush: js">escape('abc123'); // "abc123" -escape('äöü'); // "%E4%F6%FC" -escape('ć'); // "%u0107" - -// 特殊文字 -escape('@*_+-./'); // "@*_+-./"</pre> - -<h2 id="Specifications" name="Specifications">仕様書</h2> - -<table class="standard-table"> - <thead> - <tr> - <th scope="col">仕様書</th> - </tr> - </thead> - <tbody> - <tr> - <td>{{SpecName('ESDraft', '#sec-escape-string', 'escape')}}</td> - </tr> - </tbody> -</table> - -<div class="hidden">リファレンスページにポリフィルを追加しないでください。詳しくは、 <a href="https://discourse.mozilla.org/t/mdn-rfc-001-mdn-wiki-pages-shouldnt-be-a-distributor-of-polyfills/24500">https://discourse.mozilla.org/t/mdn-rfc-001-mdn-wiki-pages-shouldnt-be-a-distributor-of-polyfills/24500</a> を参照してください。</div> - -<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2> - -<p>{{Compat("javascript.builtins.escape")}}</p> - -<h2 id="See_also" name="See_also">関連情報</h2> - -<ul> - <li>{{jsxref("encodeURI")}}</li> - <li>{{jsxref("encodeURIComponent")}}</li> - <li>{{jsxref("unescape")}}</li> -</ul> diff --git a/files/ja/web/javascript/reference/global_objects/escape/index.md b/files/ja/web/javascript/reference/global_objects/escape/index.md new file mode 100644 index 0000000000..5546f806fd --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/escape/index.md @@ -0,0 +1,70 @@ +--- +title: escape() +slug: Web/JavaScript/Reference/Global_Objects/escape +tags: + - Deprecated + - JavaScript + - メソッド +browser-compat: javascript.builtins.escape +translation_of: Web/JavaScript/Reference/Global_Objects/escape +--- +{{jsSidebar("Objects")}} + +> **Warning:** `escape()` は厳密には (「ウェブ標準から削除された」という意味で) 非推奨ではありませんが、ECMA-262 標準の [Annex B](https://www.ecma-international.org/ecma-262/9.0/index.html#sec-additional-ecmascript-features-for-web-browsers) で定義されており、その導入部には次のように書かれています。 +> +> > … この付録で規定されているすべての言語機能と動作は、 1 つ以上の望ましくない特性を持ち、レガシーな使用例がない場合は、この仕様から削除されます。… +> … プログラマーは、新しい ECMAScript のコードを書くときに、これらの機能や動作の存在を使用したり、仮定したりしてはいけません。… + +The **`escape()`** 関数は、特定の文字を 16 進数のエスケープシーケンスで置き換えた新しい文字列を計算します。 + +> **Note:** この関数は、主に URL クエリー (URL の `?` に続く部分) に使われていました。 — "`\xHH`" の形式を使用して、ふつうの文字列リテラルをエスケープするためのものでは*ありません*。 (HH は 2 桁の 16 進数であり、より高い面の Unicode 文字には「\xHH\xHHxHH」という形式が使われます。) +> +> 文字列リテラル内のエスケープされた文字は、 `\x` を `%` に置き換えてから、 `decodeURIComponent()` 関数を使用することで展開することができます。 + +## 構文 + +```js +escape(str) +``` + +### 引数 + +- `str` + - : エンコードする文字列。 + +### 返値 + +特定の文字がエスケープされた新しい文字列。 + +## 解説 + +`escape` 関数は*グローバルオブジェクト*のプロパティです。特殊文字は `@*_+-./` 以外の文字が符号化されます。 + +文字の 16 進数形式として、文字コードの値が `0xFF` 以下になる文字は 2 桁のエスケープシーケンス `%xx` が、それ以上の場合は 4 桁のエスケープシーケンス `%uxxxx` が使われます。 + +## 例 + +### escape の使用 + +```js +escape('abc123'); // "abc123" +escape('äöü'); // "%E4%F6%FC" +escape('ć'); // "%u0107" + +// 特殊文字 +escape('@*_+-./'); // "@*_+-./" +``` + +## 仕様書 + +{{Specifications}} + +## ブラウザーの互換性 + +{{Compat}} + +## 関連情報 + +- {{jsxref("encodeURI")}} +- {{jsxref("encodeURIComponent")}} +- {{jsxref("unescape")}} diff --git a/files/ja/web/javascript/reference/global_objects/promise/any/index.html b/files/ja/web/javascript/reference/global_objects/promise/any/index.html deleted file mode 100644 index bca62a9a74..0000000000 --- a/files/ja/web/javascript/reference/global_objects/promise/any/index.html +++ /dev/null @@ -1,152 +0,0 @@ ---- -title: Promise.any() -slug: Web/JavaScript/Reference/Global_Objects/Promise/any -tags: - - Experimental - - JavaScript - - Method - - NeedsCompatTable - - Promise - - Reference - - プロミス - - メソッド - - 実験的 -translation_of: Web/JavaScript/Reference/Global_Objects/Promise/any ---- -<div>{{JSRef}}</div> - -<p><code>Promise.any()</code> は {{JSxRef("Promise")}} オブジェクトの反復可能オブジェクトを受け取り、反復可能オブジェクトの中にあるプロミスの一つが満足するとすぐに、そのプロミスの値で解決される単一のプロミスを返します。反復可能オブジェクトの中に満足可能なプロミスがない場合 (与えられたプロミスがすべて拒否された場合)、返されたプロミスは {{JSxRef("AggregateError")}} という、個々のエラーをグループ化した {{JSxRef("Error")}} の新しいサブクラスで拒否されます。本質的には、このメソッドは {{JSxRef("Promise.all()")}} の反対です。</p> - -<div class="blockIndicator warning"> -<p><strong>警告!</strong> <code>Promise.any()</code> メソッドは実験的であり、すべてのブラウザーが対応しているわけではありません。現在は <a href="https://github.com/tc39/proposal-promise-any" rel="external">TC39 Candidate stage (Stage 4)</a> にあります。</p> -</div> - -<h2 id="Syntax" name="Syntax">構文</h2> - -<pre class="notranslate">Promise.any(<var>iterable</var>);</pre> - -<h3 id="Parameters" name="Parameters">引数</h3> - -<dl> - <dt><code><var>iterable</var></code></dt> - <dd><a href="/ja/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterable_protocol">反復可能</a>オブジェクト、例えば {{JSxRef("Array")}} です。</dd> -</dl> - -<h3 id="Return_value" name="Return_value">返値</h3> - -<ul> - <li>渡された <var>iterable</var> が空の場合は、<strong>解決済みの</strong> {{JSxRef("Promise")}}。</li> - <li>渡された <var>iterable</var> がプロミスを含んでいない場合は、<strong>非同期に解決される</strong> {{JSxRef("Promise")}}。</li> - <li>それ以外の場合は<strong>待ち状態の</strong> {{JSxRef("Promise")}}。ここで返されたプロミスは、与えられた反復可能オブジェクト内のいずれかのプロミスが満足したとき、またはすべてのプロミスが拒否されたときに、非同期的に (スタックが空になるとすぐに) 解決または拒否されます。</li> -</ul> - -<h2 id="Description" name="Description">解説</h2> - -<p>このメソッドは、最初に満足するプロミスを返すのに便利です。1つのプロミスが満足した後に短絡するので、1つのプロミスが見つかったら他のプロミスが満足するのを待つことはありません。 {{JSxRef("Promise.all()")}} が満足した値の<em>配列</em>を返すのとは異なり、 (少なくとも1つのプロミスが満足したと仮定すると) 満足した値は 1 つしか得られません。これは、1つのプロミスが満足する必要があるが、どちらのプロミスが満足するかは関係ないときに有益な場合があります。また {{JSxRef("Promise.race()")}} が最初に<em>完了した</em>値 (満足または拒否のいずれか) を返すのとは異なり、このメソッドは最初に<em>満足した</em>値を返します。このメソッドは、最初のプロミスが満足するまでは、すべての拒否されたプロミスを無視します。</p> - -<h3 id="Fulfilment" name="Fulfilment">満足</h3> - -<p>渡されたプロミスのうちのいずれかが満足した場合、返却されるプロミスは他のプロミスが満足または拒否されているかどうかにかかわらず、満足したプロミスの値で非同期に満足します。</p> - -<ul> - <li>空の <var>iterable</var> が渡された場合は、このメソッドはすでに解決済みのプロミスを (同期的に) 返します。</li> - <li>渡されたプロミスのいずれかが満足するか、プロミスがない場合は、 <code>Promise.any</code> で返されるプロミスは非同期で満足します。</li> -</ul> - -<h3 id="Rejection" name="Rejection">拒否</h3> - -<p>渡されたすべてのプロミスが拒否された場合、 <code>Promise.any</code> は {{JSxRef("AggregateError")}} オブジェクトで非同期に拒否され、これは{{JSxRef("Error")}} を継承しており、拒否された値の配列を持つ <code>errors</code> プロパティを含みます。</p> - -<h2 id="Examples" name="Examples">例</h2> - -<h3 id="First_to_fulfil" name="First_to_fulfil">最初に満足するもの</h3> - -<p><code>Promise.any()</code> は、先に拒否されたプロミスがあったとしても、最初に満足したプロミスで解決されます。これは {{jsxref("Promise.race()")}} が最初に決定したプロミスで解決または拒否されるのとは対照的です。</p> - -<pre class="brush: js notranslate">const pErr = new Promise((resolve, reject) => { - reject("Always fails"); -}); - -const pSlow = new Promise((resolve, reject) => { - setTimeout(resolve, 500, "Done eventually"); -}); - -const pFast = new Promise((resolve, reject) => { - setTimeout(resolve, 100, "Done quick"); -}); - -Promise.any([pErr, pSlow, pFast]).then((value) => { - console.log(value); - // pFast fulfils first -}) -// 期待される出力: "Done quick" -</pre> - -<h3 id="Rejections_with_AggregateError" name="Rejections_with_AggregateError">AggregateError での拒否</h3> - -<p><code>Promise.any()</code> は満足したプロミスがないと {{jsxref("AggregateError")}} で拒否されます。</p> - -<pre class="brush: js notranslate">const pErr = new Promise((resolve, reject) => { - reject('Always fails'); -}); - -Promise.any([pErr]).catch((err) => { - console.log(err); -}) -// 期待される出力: "AggregateError: No Promise in Promise.any was resolved" -</pre> - -<h3 id="Displaying_the_first_image_loaded" name="Displaying_the_first_image_loaded">最初に読み込まれた画像の表示</h3> - -<p>この例では、画像を読み込んで blob を返す関数があります。 <code>Promise.any()</code> を使用して二つの画像を読み込み、先に利用可能になった方 (つまり、プロミスが解決された方) を表示します。</p> - -<pre class="brush: js notranslate">function fetchAndDecode(url) { - return fetch(url).then(response => { - if(!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } else { - return response.blob(); - } - }) -} - -let coffee = fetchAndDecode('coffee.jpg'); -let tea = fetchAndDecode('tea.jpg'); - -Promise.any([coffee, tea]).then(value => { - let objectURL = URL.createObjectURL(value); - let image = document.createElement('img'); - image.src = objectURL; - document.body.appendChild(image); -}) -.catch(e => { - console.log(e.message); -});</pre> - -<h2 id="Specifications" name="Specifications">仕様書</h2> - -<table class="standard-table"> - <thead> - <tr> - <th scope="col">仕様書</th> - </tr> - </thead> - <tbody> - <tr> - <td>{{SpecName('Promise.any')}}</td> - </tr> - </tbody> -</table> - -<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2> - -<p>{{Compat("javascript.builtins.Promise.any")}}</p> - -<h2 id="See_also" name="See_also">関連情報</h2> - -<ul> - <li>{{JSxRef("Promise")}}</li> - <li>{{JSxRef("Promise.allSettled()")}}</li> - <li>{{JSxRef("Promise.all()")}}</li> - <li>{{JSxRef("Promise.race()")}}</li> -</ul> diff --git a/files/ja/web/javascript/reference/global_objects/promise/any/index.md b/files/ja/web/javascript/reference/global_objects/promise/any/index.md new file mode 100644 index 0000000000..e68101da41 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/promise/any/index.md @@ -0,0 +1,136 @@ +--- +title: Promise.any() +slug: Web/JavaScript/Reference/Global_Objects/Promise/any +tags: + - JavaScript + - メソッド + - プロミス + - Reference + - Polyfill +browser-compat: javascript.builtins.Promise.any +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/any +--- +{{JSRef}} + +`Promise.any()` は {{JSxRef("Promise")}} オブジェクトの集合の反復可能オブジェクトを受け取り、反復可能オブジェクトの中にあるプロミスの一つが履行されるとすぐに、そのプロミスの値で解決される単一のプロミスを返します。反復可能オブジェクトの中に履行されたプロミスがない場合 (与えられたプロミスがすべて拒否された場合)、返されたプロミスは {{JSxRef("AggregateError")}} という、個々のエラーをグループ化した {{JSxRef("Error")}} の新しいサブクラスで拒否されます。 + +{{EmbedInteractiveExample("pages/js/promise-any.html")}} + +## 構文 + + Promise.any(iterable); + +### 引数 + +- `iterable` + - : [反復可能](/ja/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol)オブジェクト、例えば {{JSxRef("Array")}} です。 + +### 返値 + +- 渡された*反復可能*オブジェクトが空の場合は、**拒否済みの** {{JSxRef("Promise")}} です。 +- 渡された*反復可能*オブジェクトにプロミスがなかった場合は、**非同期に解決**される {{JSxRef("Promise")}} です。 +- それ以外の場合は**待ち状態**の {{JSxRef("Promise")}} です。ここで返されたプロミスは、与えられた反復可能オブジェクト内のいずれかのプロミスが解決されたとき、またはすべてのプロミスが拒否されたとき、**非同期的に** (スタックが空になるとすぐに) 解決または拒否されます。 + +## 解説 + +このメソッドは、最初に履行されたプロミスを返すのに便利です。 1 つのプロミスが履行した後に短絡するので、 1 つのプロミスが見つかったら他のプロミスが履行されるのを待つことはありません。 {{JSxRef("Promise.all()")}} が履行値の*配列*を返すのとは異なり、 (少なくとも 1 つのプロミスが履行したと仮定すると) 履行値は 1 つしか得られません。これは、 1 つのプロミスが履行される必要があるが、どのプロミスが履行されるかは関係ないときに有益な場合があります。なお、もう一つの違いとして、このメソッドは*空の反復可能*オブジェクトを受け取ったときには拒否されます。 + +また、 {{JSxRef("Promise.race()")}} が最初に*決定*された値 (履行されたか拒否されたか) を返すのとは異なり、このメソッドは最初に*履行*された値を返します。このメソッドは、最初にプロミスが履行されるまで、すべての拒否されたプロミスを無視します。 + +### 履行の場合 + +返却されたプロミスは、引数として渡された*反復可能*オブジェクトの中で**最初に**解決された値 (またはプロミスではない値) で解決します。 + +- 空でない*反復可能*オブジェクトが渡され、**いずれか**のプロミスが履行されたか、プロミスではなかった場合、このメソッドから返却されるプロミスは非同期に履行されます。 + +### 拒否の場合 + +渡されたすべてのプロミスが拒否された場合、 `Promise.any` は {{JSxRef("AggregateError")}} オブジェクトで非同期に拒否されます。これはを継承しており、拒否された値の配列を持つ errors` プロパティを含みます。 + +- 空の*反復可能*オブジェクトが渡された場合、このメソッドから返却されたプロミスは同期的に拒否されます。拒否の理由は `AggregateError` オブジェクトであり、その `errors` プロパティは空の配列になります。 + +## 例 + +### 最初に履行されるもの + +`Promise.any()` は、先に拒否されたプロミスがあったとしても、最初に履行されたプロミスで解決されます。これは {{jsxref("Promise.race()")}} が、最初に決定されたプロミスで解決または拒否されるのとは対照的です。 + +```js +const pErr = new Promise((resolve, reject) => { + reject("Always fails"); +}); + +const pSlow = new Promise((resolve, reject) => { + setTimeout(resolve, 500, "Done eventually"); +}); + +const pFast = new Promise((resolve, reject) => { + setTimeout(resolve, 100, "Done quick"); +}); + +Promise.any([pErr, pSlow, pFast]).then((value) => { + console.log(value); + // pFast fulfils first +}) +// 期待される出力: "Done quick" +``` + +### AggregateError での拒否 + +`Promise.any()` は履行されたプロミスがないと {{jsxref("AggregateError")}} で拒否されます。 + +```js +const pErr = new Promise((resolve, reject) => { + reject('Always fails'); +}); + +Promise.any([pErr]).catch((err) => { + console.log(err); +}) +// 期待される出力: "AggregateError: No Promise in Promise.any was resolved" +``` + +### 最初に読み込まれた画像の表示 + +この例では、画像を読み込んで blob を返す関数があります。 `Promise.any()` を使用して二つの画像を読み込み、先に利用可能になった方 (つまり、プロミスが解決された方) を表示します。 + +```js +function fetchAndDecode(url) { + return fetch(url).then(response => { + if(!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } else { + return response.blob(); + } + }) +} + +let coffee = fetchAndDecode('coffee.jpg'); +let tea = fetchAndDecode('tea.jpg'); + +Promise.any([coffee, tea]).then(value => { + let objectURL = URL.createObjectURL(value); + let image = document.createElement('img'); + image.src = objectURL; + document.body.appendChild(image); +}) +.catch(e => { + console.log(e.message); +}); +``` + +## 仕様書 + +{{Specifications}} + +## ブラウザーの互換性 + +{{Compat}} + +## 関連情報 + +- `Promise.any` のポリフィルは [`core-js`](https://github.com/zloirock/core-js#ecmascript-promise) で利用できます +- {{JSxRef("Promise")}} +- {{JSxRef("Promise.allSettled()")}} +- {{JSxRef("Promise.all()")}} +- {{JSxRef("Promise.race()")}} diff --git a/files/ja/web/javascript/reference/global_objects/promise/catch/index.html b/files/ja/web/javascript/reference/global_objects/promise/catch/index.html index 4b2d016a74..277bda3b8a 100644 --- a/files/ja/web/javascript/reference/global_objects/promise/catch/index.html +++ b/files/ja/web/javascript/reference/global_objects/promise/catch/index.html @@ -11,7 +11,7 @@ translation_of: Web/JavaScript/Reference/Global_Objects/Promise/catch --- <div>{{JSRef}}</div> -<p><code><strong>catch()</strong></code> メソッドは <code>Promise</code> を返しますが、拒絶された場合のみ扱います。 {{jsxref("Promise.then", "Promise.prototype.then(undefined, onRejected)")}} の呼び出しと同じ動作をします (実際、 <code>obj.catch(onRejected)</code> の呼び出しは内部的に <code>obj.then(undefined, onRejected)</code> を呼び出しています)。つまり、返値を <code>undefined</code> にフォールバックしたい場合でも、 <code>onRejected</code> 関数を提供する必要があります。 - 例えば、 <code>obj.catch(() => {})</code> のようにします。</p> +<p><code><strong>catch()</strong></code> メソッドは <code>Promise</code> を返しますが、拒否された場合のみ扱います。 {{jsxref("Promise.then", "Promise.prototype.then(undefined, onRejected)")}} の呼び出しと同じ動作をします (実際、 <code>obj.catch(onRejected)</code> の呼び出しは内部的に <code>obj.then(undefined, onRejected)</code> を呼び出しています)。つまり、返値を <code>undefined</code> にフォールバックしたい場合でも、 <code>onRejected</code> 関数を提供する必要があります。 - 例えば、 <code>obj.catch(() => {})</code> のようにします。</p> <div>{{EmbedInteractiveExample("pages/js/promise-catch.html")}}</div> @@ -33,9 +33,9 @@ p.catch(function(<var>reason</var>) { <dd><code>Promise</code> が失敗した時に呼び出される {{jsxref("Function")}} です。この関数は一つの引数を持ちます。 <dl> <dt><code><var>reason</var></code></dt> - <dd>拒絶された理由です。</dd> + <dd>拒否された理由です。</dd> </dl> - <code>catch()</code> で返される Promise は、 <code><var>onRejected</var></code> がエラーを発生させた場合、または返される Promise それ自体が拒絶された場合は、拒絶となります。それ以外の場合は、解決となります。</dd> + <code>catch()</code> で返される Promise は、 <code><var>onRejected</var></code> がエラーを発生させた場合、または返される Promise それ自体が拒否された場合は、拒否となります。それ以外の場合は、解決となります。</dd> </dl> <h3 id="Return_value" name="Return_value">返値</h3> diff --git a/files/ja/web/javascript/reference/global_objects/promise/index.html b/files/ja/web/javascript/reference/global_objects/promise/index.html deleted file mode 100644 index 3b1d149baa..0000000000 --- a/files/ja/web/javascript/reference/global_objects/promise/index.html +++ /dev/null @@ -1,365 +0,0 @@ ---- -title: Promise -slug: Web/JavaScript/Reference/Global_Objects/Promise -tags: - - Class - - ECMAScript 2015 - - JavaScript - - Promise - - Reference - - クラス - - プロミス -translation_of: Web/JavaScript/Reference/Global_Objects/Promise ---- -<div>{{JSRef}}</div> - -<p><strong><code>Promise</code></strong> オブジェクトは非同期処理の最終的な完了処理 (もしくは失敗) およびその結果の値を表現します。</p> - -<p>プロミスの挙動と使用法について学ぶには、最初に <a href="/ja/docs/Web/JavaScript/Guide/Using_promises">Promise の使用</a>をお読みください。</p> - -<h2 id="Description" name="Description">解説</h2> - -<p><code><strong>Promise</strong></code> インターフェイスは作成時点では分からなくてもよい値へのプロキシです。 Promise を用いることで、非同期アクションの成功や失敗に対するハンドラーを関連付けることができます。これにより、非同期メソッドは、最終的な値を返すのではなく、未来のある時点で値を持つ Promise を返すことで、同期メソッドと同じように値を返すことができるようになります。</p> - -<p><code>Promise</code> の状態は以下のいずれかとなります。</p> - -<ul> - <li><ruby>待機<rp> (</rp><rt><em>pending</em></rt></ruby>: 初期状態。成功も失敗もしていません。</li> - <li><ruby>満足<rp> (</rp><rt><em>fulfilled</em></rt><rp>)</rp></ruby>: 処理が成功して完了したことを意味します。</li> - <li><ruby>拒絶<rp> (</rp><rt><em>rejected</em></rt><rp>)</rp></ruby>: 処理が失敗したことを意味します。</li> -</ul> - -<p>待機状態のプロミスは、何らかの値を持つ満足 (<em>fulfilled</em>) 状態、もしくは何らかの理由 (エラー) を持つ拒絶 (<em>rejected</em>) 状態のいずれかに変わります。そのどちらとなっても、<code>then</code> メソッドによって関連付けられたハンドラーが呼び出されます。 (対応するハンドラーが割り当てられたとき、既にプロミスが成功または失敗していても、そのハンドラーは呼ばれます。よって、非同期処理とその関連付けられたハンドラーとの競合は発生しません。)</p> - -<p><code>{{JSxRef("Promise.then", "Promise.prototype.then()")}}</code> メソッドと <code>{{JSxRef("Promise.catch", "Promise.prototype.catch()")}}</code> メソッドもまた Promise を返すので、これらをチェーン (連鎖) させることができます。</p> - -<p><img alt="" src="https://mdn.mozillademos.org/files/15911/promises.png" style="height: 297px; width: 801px;"></p> - -<div class="blockIndicator note"> -<p><strong>混乱を避けるために:</strong> Scheme に代表されるいくつかの言語では、遅延評価や計算を延期する機構を持っており、これらも "Promise" と呼ばれます。 JavaScript における Promise は、すでに起きつつある処理を表します。そしてこの処理はコールバックを使うことでチェーンさせることができます。式を遅延評価する方法を探しているのであれば、引数なしの<a href="/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions">アロー関数</a>を考えてください。 <code>f = () => <em>expression</em></code> のように実現でき、遅延評価される式が作成され、 <code>f()</code> を呼ぶことでその式を評価できます。</p> -</div> - -<div class="blockIndicator note"> -<p><strong>注</strong>: Promise は fulfilled か failed のどちらかになった場合は、 pending ではなく settled と呼ばれます。また解決 (<em>resolved</em>) という用語も目にされたことがあると思います。解決とは、Promise が解決または他の promise の状態にマッチするために" locked in "したことを意味します。<a href="https://github.com/domenic/promises-unwrapping/blob/master/docs/states-and-fates.md">States and fates</a> では、 Promise の技術についてより詳細に述べられています。</p> -</div> - -<h3 id="Chained_Promises" name="Chained_Promises">連鎖したプロミス</h3> - -<p><code>promise.then()</code>, <code>promise.catch()</code>, <code>promise.finally()</code> の各メソッドは、決定したプロミスにさらなるアクションを関連付けるために使用されます。これらのメソッドはまた、新しく生成されたプロミスオブジェクトを返します。例えば、このようになります。</p> - -<dl> - <dd> - <pre class="brush: js notranslate">const myPromise = - (new Promise(myExecutorFunc)) - .then(handleFulfilledA,handleRejectedA) - .then(handleFulfilledB,handleRejectedB) - .then(handleFulfilledC,handleRejectedC); - -// または、おそらく次の方がよい ... - -const myPromise = - (new Promise(myExecutorFunc)) - .then(handleFulfilledA) - .then(handleFulfilledB) - .then(handleFulfilledC) - .catch(handleRejectedAny);</pre> - </dd> -</dl> - -<p>拒絶されたプロミスの処理が早すぎると、プロミスの連鎖のさらに下の方に影響を及ぼします。エラーはすぐに処理しなければならないので、選択の余地がないこともあります。 (結果を処理するためのテクニックについては、下記の例の <code>throw -999</code> を参照してください。) 一方で、すぐに必要がない場合は、最後の .catch() 文までエラー処理をしない方がシンプルです。</p> - -<p>これら2つの関数のシグネチャはシンプルで、任意の型の引数を1つだけ受け取ることができます。これらの関数を書くのはプログラマーです。これらの関数の終了条件は、チェーン内の次のプロミスの「解決」状態を決定します。 <code>throw</code> 以外の終了条件は "解決" の状態を生み出し、一方、 <code>throw</code> で終了すると "拒否" の状態を生み出します。</p> - -<pre class="brush: js notranslate">handleFulfilled(value) { /*...*/; return nextValue; } -handleRejection(reason) { /*...*/; throw nextReason; } -handleRejection(reason) { /*...*/; return nextValue; }</pre> - -<p>返される <code>nextValue</code> は、別のプロミスオブジェクトにすることもでき、この場合はプロミスは動的にチェーンに挿入されます。</p> - -<p><code>.then()</code> が適切な関数欠いている場合、処理は単純にチェーンの次のリンクへと続きます。したがってチェーンは、すべての <code>handleRejection</code> を最後の <code>.catch()</code> まで、安全に省略することができます。 同様に、<code>.catch()</code> は、実際には <code>handleFulfilled</code> 用のスロットのないただの <code>.then()</code> です。</p> - -<p>プロミスのチェーンはロシアの人形のように入れ子にすることができますが、スタックの最上位のように取り出します。チェーンの最初のプロミスは最も深いところに入れ子になり、最初に取り出されます。</p> - -<pre class="notranslate">(promise D, (promise C, (promise B, (promise A) ) ) )</pre> - -<p><code>nextValue</code> がプロミスである場合、その効果は動的な置換です。 <code>return</code> によってプロミスが取り出されますが、 <code>nextValue</code> のプロミスはその場所に押し込まれます。上に示した入れ子では、"promise B" に関連付けられた <code>.then()</code> が "promise X" の <code>nextValue</code> を返すとします。 結果としての入れ子は以下のようになります。</p> - -<pre class="notranslate">(promise D, (promise C, (promise X) ) )</pre> - -<p>プロミスは複数の入れ子に参加することができます。以下のコードでは、 <code>promiseA</code> が「確定」状態に移行すると、 <code>.then()</code> の両方のインスタンスが呼び出されます。</p> - -<pre class="brush: js notranslate">const promiseA = new Promise(myExecutorFunc); -const promiseB = promiseA.then(handleFulfilled1, handleRejected1); -const promiseC = promiseA.then(handleFulfilled2, handleRejected2); -</pre> - -<p>既に「解決済み」のプロミスにアクションを割り当てることができます。その場合、アクションは (適切であれば) 最初の非同期の機会に実行されます。プロミスは非同期であることが保証されていることに注意してください。したがって、既に「解決済み」のプロミスに対するアクションは、スタックがクリアされ、クロックティックが経過した後にのみ実行されます。この効果は <code>setTimeout(action,10)</code> とよく似ています</p> - -<pre class="brush: js notranslate">const promiseA = new Promise( (resolutionFunc,rejectionFunc) => { - resolutionFunc(777); -}); -// この時点で、 "promiseA" はすでに解決されています。 -promiseA.then( (val) => console.log("asynchronous logging has val:",val) ); -console.log("immediate logging"); - -// 以下の順序で出力が行われます。 -// immediate logging -// asynchronous logging has val: 777 -</pre> - -<h2 id="Constructor" name="Constructor">コンストラクター</h2> - -<dl> - <dt>{{jsxref("Promise/Promise", "Promise()")}}</dt> - <dd>新しい <code>Promise</code> オブジェクトを生成します。このコンストラクターは主にまだプロミスに対応していない関数をラップするために使われます。</dd> -</dl> - -<h2 id="Static_methods" name="Static_methods">静的メソッド</h2> - -<dl> - <dt>{{JSxRef("Promise.all", "Promise.all(iterable)")}}</dt> - <dd>すべてのプロミスが解決されるか、拒否されるかするまで待ちます。</dd> - <dd>返却されたプロミスが解決された場合、解決されたプロミスが、複数のプロミスが含まれる iterable で定義された通りの順番で入った集合配列の値によって解決されます。</dd> - <dd>拒否された場合は、 iterable の中で拒否された最初のプロミスの理由によって拒否されます。</dd> - <dt>{{JSxRef("Promise.allSettled", "Promise.allSettled(iterable)")}}</dt> - <dd>すべての Promise が完了する (それぞれが解決するか、拒否される) まで待ちます。</dd> - <dd>Promise を返し、これはすべての与えられた Promise が解決または拒否された後で、それぞれの Promise の結果を記述するオブジェクトの配列で解決されます。</dd> - <dt>{{JSxRef("Promise.any", "Promise.any(iterable)")}}</dt> - <dd>Promise オブジェクトの反復可能オブジェクトを取り、反復可能オブジェクトの中のプロミスのうちの一つが満足され次第、そのプロミスから受け取った値で解決する単一のプロミスを返します。</dd> - <dt>{{JSxRef("Promise.race", "Promise.race(iterable)")}}</dt> - <dd>Promise のうちの1つが解決または拒否されるまで待ちます。</dd> - <dd>返された Promise が解決された場合、 iterable の中で最初に解決された Promise の値によって解決されます。</dd> - <dd>拒否された場合、最初に拒否された Promise の理由によって拒否されます。</dd> - <dt>{{JSxRef("Promise.reject", "Promise.reject(reason)")}}</dt> - <dd>与えられた理由で拒否された新しい <code>Promise</code> オブジェクトを返します。</dd> - <dt>{{JSxRef("Promise.resolve", "Promise.resolve(value)")}}</dt> - <dd>与えられた値で解決された新しい <code>Promise</code> オブジェクトを返します。もし値が thenable (つまり <code>then</code> メソッドを持っているオブジェクト) ならば、返される Promise はその thenable をたどり、その結果を採用します。そうでなければ、返される Promise は与えられた値で解決されます。</dd> - <dd>一般に、ある値がプロミスかどうかがわからない場合は、{{JSxRef("Promise.resolve", "Promise.resolve(value)")}} を使って Promise にして扱います。</dd> -</dl> - -<h2 id="Instance_methods" name="Instance_methods">インスタンスメソッド</h2> - -<dl> - <dt>{{jsxref("Promise.prototype.catch()")}}</dt> - <dd>プロミスに失敗ハンドラーコールバックを付加します。呼ばれるとコールバックの返値、または、オリジナルのプロミスが成功しているなら、その成功値によって完了している新しいプロミスを返します。</dd> - <dt>{{jsxref("Promise.prototype.then()")}}</dt> - <dd>プロミスに成功ハンドラーと失敗ハンドラーを付加します。呼ばれたハンドラーの戻り値によって解決している新しいプロミスを返します。または、プロミスが扱われなかった場合 (つまり <code>onFulfilled</code> や <code>onRejected</code> が関数でない場合) には、元の完了した値に解決しているプロミスを返します。</dd> - <dt>{{jsxref("Promise.prototype.finally()")}}</dt> - <dd>プロミスにハンドラーを付加し、元のプロミスが解決されたときに解決される新しいプロミスを返します。このハンドラーは、成功か失敗かに関わらず、元のプロミスが完了したときに呼ばれます。</dd> -</dl> - -<h2 id="Examples" name="Examples">例</h2> - -<h3 id="Basic_Example" name="Basic_Example">基本的な使用例</h3> - -<pre class="brush: js; notranslate">let myFirstPromise = new Promise((resolve, reject) => { - // We call resolve(...) when what we were doing asynchronously was successful, and reject(...) when it failed. - // In this example, we use setTimeout(...) to simulate async code. - // In reality, you will probably be using something like XHR or an HTML5 API. - setTimeout( function() { - resolve("Success!") // Yay! Everything went well! - }, 250) -}) - -myFirstPromise.then((successMessage) => { - // successMessage is whatever we passed in the resolve(...) function above. - // It doesn't have to be a string, but if it is only a succeed message, it probably will be. - console.log("Yay! " + successMessage) -}); - -</pre> - -<h3 id="Example_with_diverse_situations" name="Example_with_diverse_situations">多様な状況に対応した例</h3> - -<p>この例では、プロミス機能を使用するための多様なテクニックと、発生する可能性のある多様な状況を示しています。これを理解するには、まずコードブロックの一番下までスクロールして、プロミスの連鎖を調べてください。最初のプロミスが提供されると、プロミスの連鎖が続きます。このチェーンは <code>.then()</code> の呼び出しで構成され、通常は (必ずしもそうとは限りませんが) 最後に単一の <code>.catch()</code> があり、オプションで <code>.finally()</code> が続きます。この例では、プロミスチェーンはカスタムで書かれた <code>new Promise()</code> コンストラクターによって開始されますが、実際には、プロミスチェーンは通常、プロミスを返す API 関数 (他の誰かが書いたもの) から開始されます。</p> - -<p>関数 <code>tetheredGetNumber()</code> の例では、非同期呼び出しを設定している間、またはコールバック内で、またはその両方で <code>reject()</code> を使用してプロミスを生成することを示しています。 関数 <code>promiseGetWord()</code> は、API 関数がどのように自己完結型の方法でプロミスを生成して返すかを示しています。</p> - -<p>関数 <code>troubleWithGetNumber()</code> は <code>throw()</code> で終わることに注意してください。これは、 ES6 のプロミスチェーンでは、エラーが発生した後で、 "throw()" がなく、エラーが "fixed" であるようにみえても、すべての <code>.then()</code> のプロミスを通過するため、強制的に行われています。これは面倒なので、 <code>.then()</code> プロミスのチェーン全体で <code>rejectionFunc</code> を省略して、最終的な <code>catch()</code> で単一の <code>rejectionFunc</code> を使用するのが一般的です。 別の方法としては、特別な値を投げるという方法があります (この場合は"-999" ですが、カスタムのエラー種別の方が適切です)。</p> - -<p>このコードは NodeJS で実行できます。実際にエラーが発生しているのを見ることで理解度が高まります。より多くのエラーを強制的に発生させるには、 <code>threshold</code> の値を変更します。</p> - -<pre class="brush: js notranslate">"use strict"; - -// To experiment with error handling, "threshold" values cause errors randomly -const THRESHOLD_A = 8; // can use zero 0 to guarantee error - -function tetheredGetNumber(resolve, reject) { - try { - setTimeout( - function() { - const randomInt = Date.now(); - const value = randomInt % 10; - try { - if(value >= THRESHOLD_A) { - throw new Error(`Too large: ${value}`); - } - } catch(msg) { - reject(`Error in callback ${msg}`); - } - resolve(value); - return; - }, 500); - // To experiment with error at set-up, uncomment the following 'throw'. - // throw new Error("Bad setup"); - } catch(err) { - reject(`Error during setup: ${err}`); - } - return; -} - -function determineParity(value) { - const isOdd = value % 2 ? true : false ; - const parityInfo = { theNumber: value, isOdd: isOdd }; - return parityInfo; -} - -function troubleWithGetNumber(reason) { - console.error(`Trouble getting number: ${reason}`); - throw -999; // must "throw" something, to maintain error state down the chain -} - -function promiseGetWord(parityInfo) { - // The "tetheredGetWord()" function gets "parityInfo" as closure variable. - var tetheredGetWord = function(resolve,reject) { - const theNumber = parityInfo.theNumber; - const threshold_B = THRESHOLD_A - 1; - if(theNumber >= threshold_B) { - reject(`Still too large: ${theNumber}`); - } else { - parityInfo.wordEvenOdd = parityInfo.isOdd ? 'odd' : 'even'; - resolve(parityInfo); - } - return; - } - return new Promise(tetheredGetWord); -} - -(new Promise(tetheredGetNumber)) - .then(determineParity,troubleWithGetNumber) - .then(promiseGetWord) - .then((info) => { - console.log("Got: ",info.theNumber," , ", info.wordEvenOdd); - return info; - }) - .catch((reason) => { - if(reason === -999) { - console.error("Had previously handled error"); - } - else { - console.error(`Trouble with promiseGetWord(): ${reason}`); - } - }) - .finally((info) => console.log("All done")); - -</pre> - -<h3 id="Advanced_Example" name="Advanced_Example">応用例</h3> - -<div class="hidden"> -<pre class="brush: html notranslate"><button id="btn">Make a promise!</button> -<div id="log"></div> -</pre> -</div> - -<p>以下の例は <code>Promise</code> の仕組みを示したものです。 <code>testPromise()</code> メソッドは {{HTMLElement("button")}} をクリックする度に呼び出されます。<code>testPromise()</code> メソッドは、 {{domxref("window.setTimeout()")}} を用いて、1秒から 3秒のランダムな時間の後、メソッドがこれまでに呼ばれた回数で成功する Promise を作成します。 <code>Promise()</code> コンストラクターは Promise を作成するために使用されます。</p> - -<p>プロミスが満足したことは、 {{JSxRef("Promise.prototype.then()","p1.then()")}} で設定されたコールバックによって記録されます。この記録から、メソッドの同期処理部分が、 Promise による非同期処理からどのように分離されているかがわかります。</p> - -<pre class="brush: js; notranslate">'use strict'; -var promiseCount = 0; - -function testPromise() { - let thisPromiseCount = ++promiseCount; - - let log = document.getElementById('log'); - log.insertAdjacentHTML('beforeend', thisPromiseCount + - ') 開始 (<small>同期処理開始</small>)<br/>'); - - // 新しい Promise を作成: 1~3秒後に結果を返すことを約束します - let p1 = new Promise( - // executor 関数は Promise の成功または失敗に応じて呼ばれます - // - (resolve, reject) => { - log.insertAdjacentHTML('beforeend', thisPromiseCount + - ') Promise 開始 (<small>非同期処理開始</small>)<br/>'); - // 非同期を作成するための一例です - window.setTimeout( - function() { - // 約束を果たしました! - resolve(thisPromiseCount); - }, Math.random() * 2000 + 1000); - } - ); - - // Promise が成功した時に何をするかを定めます then() で成功した時 - // catch() で失敗した時 - p1.then( - // メッセージと値を記録します - function(val) { - log.insertAdjacentHTML('beforeend', val + - ') Promise 成功 (<small>非同期処理終了</small>)<br/>'); - }).catch( - // 失敗した理由を記録します - (reason) => { - console.log('Handle rejected promise ('+reason+') here.'); - }); - - log.insertAdjacentHTML('beforeend', thisPromiseCount + - ') Promise は作成されました (<small>同期処理終了</small>)<br/>'); -}</pre> - -<div class="hidden"> -<pre class="brush: js; notranslate">if ("Promise" in window) { - let btn = document.getElementById("btn"); - btn.addEventListener("click",testPromise); -} else { - log = document.getElementById('log'); - log.innerHTML = "Live example not available as your browser doesn't support the <code>Promise<code> interface."; -} -</pre> -</div> - -<p>この例はボタンをクリックすると実行されます。 (ブラウザーが <code>Promise</code> に対応している必要があります。)</p> - -<p>短い時間の間に何度かボタンをクリックすると、それぞれの promise が次々と成功するのがわかります。</p> - -<p>{{EmbedLiveSample("Advanced_Example", "500", "200")}}</p> - -<h3 id="Loading_an_image_with_XHR" name="Loading_an_image_with_XHR">XHR による画像の読み込み</h3> - -<p><code>Promise</code> と {{domxref("XMLHttpRequest")}} で画像を読み込む別の例は、 MDN GitHub <a href="https://github.com/mdn/js-examples/tree/master/promises-test">js-examples</a> リポジトリにあり、<a href="https://mdn.github.io/js-examples/promises-test/">動作を確認する</a>ことができます。それぞれの行のコメントで Promise と XHR の構造がよくわかるはずです。</p> - -<h2 id="Specifications" name="Specifications">仕様書</h2> - -<table class="standard-table"> - <tbody> - <tr> - <th scope="col">仕様書</th> - </tr> - <tr> - <td>{{SpecName('ESDraft', '#sec-promise-objects', 'Promise')}}</td> - </tr> - </tbody> -</table> - -<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2> - -<p>{{Compat("javascript.builtins.Promise")}}</p> - -<h2 id="See_also" name="See_also">関連情報</h2> - -<ul> - <li><a href="/ja/docs/Web/JavaScript/Guide/Using_promises">プロミスの使用</a></li> - <li><a href="http://promisesaplus.com/">Promises/A+ specification</a></li> - <li><a href="https://medium.com/@ramsunvtech/promises-of-promise-part-1-53f769245a53">Venkatraman.R - JS Promise (Part 1, Basics)</a></li> - <li><a href="https://medium.com/@ramsunvtech/js-promise-part-2-q-js-when-js-and-rsvp-js-af596232525c#.dzlqh6ski">Venkatraman.R - JS Promise (Part 2 - Using Q.js, When.js and RSVP.js)</a></li> - <li><a href="https://tech.io/playgrounds/11107/tools-for-promises-unittesting/introduction">Venkatraman.R - Tools for Promises Unit Testing</a></li> - <li><a href="http://www.html5rocks.com/en/tutorials/es6/promises/">Jake Archibald: JavaScript Promises: There and Back Again</a></li> - <li><a href="http://de.slideshare.net/domenicdenicola/callbacks-promises-and-coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript">Domenic Denicola: Callbacks, Promises, and Coroutines – Asynchronous Programming Patterns in JavaScript</a></li> - <li><a href="http://www.mattgreer.org/articles/promises-in-wicked-detail/">Matt Greer: JavaScript Promises ... In Wicked Detail</a></li> - <li><a href="https://www.promisejs.org/">Forbes Lindesay: promisejs.org</a></li> - <li><a href="https://github.com/anonyco/SPromiseMeSpeedJS/blob/master/README.md">Speed-polyfill to polyfill both promise availability and promise performance.</a></li> - <li><a href="https://github.com/jakearchibald/es6-promise/">Promise polyfill</a></li> - <li><a href="https://www.udacity.com/course/javascript-promises--ud898">Udacity: JavaScript Promises</a></li> -</ul> diff --git a/files/ja/web/javascript/reference/global_objects/promise/index.md b/files/ja/web/javascript/reference/global_objects/promise/index.md new file mode 100644 index 0000000000..821495840f --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/promise/index.md @@ -0,0 +1,435 @@ +--- +title: Promise +slug: Web/JavaScript/Reference/Global_Objects/Promise +tags: + - クラス + - ECMAScript 2015 + - JavaScript + - Promise + - Reference + - promise.all + - Polyfill +browser-compat: javascript.builtins.Promise +translation_of: Web/JavaScript/Reference/Global_Objects/Promise +--- +{{JSRef}} + +**`Promise`** オブジェクトは、非同期処理の完了 (もしくは失敗) の結果およびその結果の値を表します。 + +{{AvailableInWorkers}} + +プロミスの挙動と使用法について学ぶには、最初に[プロミスの使用](/ja/docs/Web/JavaScript/Guide/Using_promises)をお読みください。 + +## 解説 + +プロミス (**`Promise`**) は、作成された時点では分からなくてもよい値へのプロキシーです。非同期のアクションの成功値または失敗理由にハンドラーを結びつけることができます。これにより、非同期メソッドは結果の値を返す代わりに、未来のある時点で値を提供する*プロミス*を返すことで、同期メソッドと同じように値を返すことができるようになります。 + +`Promise` の状態は以下のいずれかとなります。 + +- 待機 (_pending_): 初期状態。成功も失敗もしていません。 +- 履行 (_fulfilled_): 処理が成功して完了したことを意味します。 +- 拒否 (_rejected_): 処理が失敗したことを意味します。 + +待機状態のプロミスは、何らかの値を持つ履行 (_fulfilled_) 状態、もしくは何らかの理由 (エラー) を持つ拒否 (_rejected_) 状態のいずれかに変わります。そのどちらとなっても、`then` メソッドによって関連付けられたハンドラーが呼び出されます。対応するハンドラーが割り当てられたとき、既にプロミスが履行または拒否状態になっていても、そのハンドラーは呼び出されます。よって、非同期処理とその関連付けられたハンドラーとの競合は発生しません。 + +`{{JSxRef("Promise.then", "Promise.prototype.then()")}}` メソッドと `{{JSxRef("Promise.catch", "Promise.prototype.catch()")}}` メソッドもまたプロミスを返すので、これらを連鎖 (chain) させることができます。 + + + +> **Note:** Scheme に代表される一部の言語では、遅延評価や計算を延期する機構を持っており、これらも「プロミス」と呼ばれます。 JavaScript におけるプロミスは、すでに起きつつある処理を表し、この処理はコールバックを使うことで連鎖させることができます。式を遅延評価する方法を探しているのであれば、引数なしの<a href="/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions">アロー関数</a>を検討してください。 `f = () => expression` で遅延評価される式が作成でき、 `f()` を実行することで評価を実行することができます。 + +> **Note:** プロミスは履行状態または拒否状態になった場合は、待機ではなく決定 (_settled_) と呼ばれます。また解決 (_resolved_) という用語も見かけるでしょう。これはプロミスが決定したか、他のプロミスの状態に一致させるために「ロックイン」したことを表します。 [States and fates](https://github.com/domenic/promises-unwrapping/blob/master/docs/states-and-fates.md) には、プロミスの用語についての詳細説明があります。 + +### 複数のプロミスの連鎖 + +`promise.then()`, `promise.catch()`, `promise.finally()` の各メソッドは、決定したプロミスにさらなるアクションを結びつけるために使用します。 + +`.then()` メソッドは、最大で 2 つの引数を取ります。1 番目の引数は、プロミスが解決した場合のコールバック関数で、 2 番目の引数は、拒否された場合のコールバック関数です。それぞれの `.then()` は新たに生成されたプロミスオブジェクトを返します。このオブジェクトは、オプションで連鎖に使用することができます。例えば、このようになります。 + +```js +const myPromise = new Promise((resolve, reject) => { + setTimeout(() => { + resolve('foo'); + }, 300); +}); + +myPromise + .then(handleResolvedA, handleRejectedA) + .then(handleResolvedB, handleRejectedB) + .then(handleResolvedC, handleRejectedC); +``` + +`.then()` に Promise オブジェクトを返すコールバック関数がない場合でも、連鎖の次のリンクへと処理が進みます。したがって、連鎖では最後の `.catch()` まで、すべての*拒否*のコールバック関数を省略しても安全です。 + +それぞれの `.then()` で拒否されたプロミスを扱うと、プロミスの連鎖のさらに先に影響を及ぼします。エラーを直ちに処理しなければならないため、選択の余地がない場合もあります。このような場合には、連鎖的にエラー状態を維持するために、何らかの種類のエラーを発生させる必要があります。一方で、緊急の必要性がない場合は、最後の `.catch()` ステートメントまでエラー処理を行わない方がシンプルです。 `.catch()` は、実際には、単なる `.then()` からプロミスが解決されたときのためのコールバック関数のスロットを抜いたものです。 + +```js +myPromise +.then(handleResolvedA) +.then(handleResolvedB) +.then(handleResolvedC) +.catch(handleRejectedAny); +``` + +{{JSxRef("Functions/Arrow_functions", "アロー関数式", "", 1)}}をコールバック関数に使用すると、プロミス連鎖の実装は次のようになるでしょう。 + +```js +promise1 +.then(value => { return value + ' and bar'; }) +.then(value => { return value + ' and bar again'; }) +.then(value => { return value + ' and again'; }) +.then(value => { return value + ' and again'; }) +.then(value => { console.log(value) }) +.catch(err => { console.log(err) }); +``` + +プロミスの終了条件は、その連鎖内の次のプロミスの「決定」状態を決定します。解決」状態はプロミスの完了が成功したことを示し、「拒否」状態は成功しなかったことを示します。連鎖内で解決されたそれぞれのプロミスの返値は、次の `.then()` に渡され、拒否された理由は連鎖内の次の拒否ハンドラー関数に渡されます。 + +連鎖のプロミスは、ロシア人形のように入れ子になっていますが、スタックの一番上のように取り出されます。連鎖の最初のプロミスは最も深くネストされており、最初に取り出されます。 + +```plain +(promise D, (promise C, (promise B, (promise A) ) ) ) +``` + +`nextValue` がプロミスである場合、その効果は動的な置換です。 `return` によってプロミスが取り出されますが、 `nextValue` のプロミスはその場所に押し込まれます。上に示した入れ子では、"promise B" に関連付けられた `.then()` が "promise X" の `nextValue` を返すとします。 結果としての入れ子は以下のようになります。 + +```plain +(promise D, (promise C, (promise X) ) ) +``` + +プロミスは複数の入れ子に参加することができます。以下のコードでは、 `promiseA` が「決定」状態に移行すると、 `.then()` の両方のインスタンスが呼び出されます。 + +```js +const promiseA = new Promise(myExecutorFunc); +const promiseB = promiseA.then(handleFulfilled1, handleRejected1); +const promiseC = promiseA.then(handleFulfilled2, handleRejected2); +``` + +既に「決定」状態のプロミスにアクションを割り当てることができます。その場合、アクションは (適切であれば) 最初の非同期の機会に実行されます。プロミスは非同期であることが保証されていることに注意してください。したがって、既に「解決」状態のプロミスに対するアクションは、スタックがクリアされ、クロックティックが経過した後にのみ実行されます。この効果は `setTimeout(action,10)` とよく似ています + +```js +const promiseA = new Promise( (resolutionFunc,rejectionFunc) => { + resolutionFunc(777); +}); +// この時点で、 "promiseA" はすでに解決されています。 +promiseA.then( (val) => console.log("asynchronous logging has val:",val) ); +console.log("immediate logging"); + +// 以下の順序で出力が行われます。 +// immediate logging +// asynchronous logging has val: 777 +``` + +### 現行の設定オブジェクトの追跡 + +設定オブジェクト (settings object) とは、 JavaScript コードの実行時に追加情報を提供する[環境](https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object)のことです。これには、領域やモジュールマップのほか、オリジンなどの HTML 固有の情報も含まれます。現行の設定オブジェクトが追跡されるのは、特定のユーザーコードに対してどの設定オブジェクトを使用すべきかをブラウザーが確実に把握するためです。 + +これをより良く理解するために、領域がどのように問題になるかを詳しく見てみましょう。領域 (**realm**) とは、大まかに言うとグローバルオブジェクトのことです。領域の特徴は、JavaScript のコードを実行するために必要な情報をすべて保持していることです。これには [`Array`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Array) や [`Error`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Error) などのオブジェクトが含まれます。それぞれの設定オブジェクトはこれらの「コピー」を持っており、共有されていません。そのため、プロミスとの関係で予期しない動作をすることがあります。これを回避するために、**現行の設定オブジェクト** (incumbent settings object) と呼ばれるものを追跡します。これは、ある関数呼び出しを担当するユーザーコードのコンテキストに固有の情報を表します。 + +これをもう少し詳しく説明するために、文書に埋め込まれた [`<iframe>`](/ja/docs/Web/HTML/Element/iframe) がホストとどのように通信するかを見てみましょう。すべての Web API は現行の設定オブジェクトを認識しているため、以下のようにすればすべてのブラウザーで動作します。 + +```html +<!DOCTYPE html> +<iframe></iframe> <!-- we have a realm here --> +<script> // we have a realm here as well + const bound = frames[0].postMessage.bind( + frames[0], "some data", "*"); + // bound is a built-in function -- there is no user + // code on the stack, so which realm do we use? + window.setTimeout(bound); + // this still works, because we use the youngest + // realm (the incumbent) on the stack +</script> +``` + +同じ概念をプロミスに適用します。上の例を少し変えてみると、こうなります。 + +```html +<!DOCTYPE html> +<iframe></iframe> <!-- we have a realm here --> +<script> // we have a realm here as well + const bound = frames[0].postMessage.bind( + frames[0], "some data", "*"); + // bound is a built in function -- there is no user + // code on the stack -- which realm do we use? + Promise.resolve(undefined).then(bound); + // this still works, because we use the youngest + // realm (the incumbent) on the stack +</script> +``` + +これを変更して、文書内の `<iframe>` が post メッセージを待ち受けするようにすると、現行の設定オブジェクトの効果を観察することができます。 + +```html +<!-- y.html --> +<!DOCTYPE html> +<iframe src="x.html"></iframe> +<script> + const bound = frames[0].postMessage.bind(frames[0], "some data", "*"); + Promise.resolve(undefined).then(bound); +</script> +``` + +```html +<!-- x.html --> +<!DOCTYPE html> +<script> +window.addEventListener("message", (event) => { + document.querySelector("#text").textContent = "hello"; + // this code will only run in browsers that track the incumbent settings object + console.log(event); +}, false); +</script> +``` + +上記の例では、現行の設定オブジェクトが追跡されたときのみ `<iframe>` の内部のテキストが更新されます。これは、現職のものを追跡しないと、メッセージを送る環境を間違えてしまう可能性があるからです。 + +> **Note:** 現在のところ、現役の領域の追跡は Firefox では完全に実装されており、 Chrome と Safari では部分的に実装されています。 + +## コンストラクター + +- {{jsxref("Promise/Promise", "Promise()")}} + - : 新しい `Promise` オブジェクトを生成します。このコンストラクターは主に、まだプロミスに対応していない関数をラップするために使われます。 + +## 静的メソッド + +- {{JSxRef("Promise.all", "Promise.all(iterable)")}} + + - : すべてのプロミスが解決されるか、拒否されるかするまで待ちます。 + + 返却されたプロミスが解決された場合、解決されたプロミスが、複数のプロミスが含まれる反復可能オブジェクトで定義された順番で入った集合配列の値によって解決されます。 + + 拒否された場合は、反復可能オブジェクトの中で拒否された最初のプロミスの理由によって拒否されます。 + +- {{JSxRef("Promise.allSettled", "Promise.allSettled(iterable)")}} + + - : すべてのプロミスが完了する (それぞれが解決されるか、拒否される) まで待ちます。 + + これはすべての与えられたプロミスが解決または拒否された後で、それぞれのプロミスの結果を記述したオブジェクトの配列で解決される Promise を返します。 + +- {{JSxRef("Promise.any", "Promise.any(iterable)")}} + - : Promise オブジェクトの反復可能オブジェクトを取り、反復可能オブジェクトの中のプロミスのうちの一つが履行され次第、そのプロミスから受け取った値で解決する単一のプロミスを返します。 +- {{JSxRef("Promise.race", "Promise.race(iterable)")}} + + - : プロミスのうちの 1 つが解決または拒否されるまで待ちます。 + + 返されたプロミスが解決された場合、反復可能オブジェクトの中で最初に解決されたプロミスの値によって解決されます。 + + 拒否された場合、最初に拒否されたプロミスの理由によって拒否されます。 + +- {{JSxRef("Promise.reject", "Promise.reject(reason)")}} + - : 与えられた理由で拒否された新しい `Promise` オブジェクトを返します。 +- {{JSxRef("Promise.resolve", "Promise.resolve(value)")}} + + - : 与えられた値で解決された新しい `Promise` オブジェクトを返します。もし値が thenable (つまり `then` メソッドを持っているオブジェクト) ならば、返されるプロミスはその thenable をたどり、その結果を採用します。そうでなければ、返されるプロミスは与えられた値で解決されます。 + + 一般に、ある値がプロミスであるかどうかがわからない場合は、代わりに {{JSxRef("Promise.resolve", "Promise.resolve(value)")}} を使用し、返値をプロミスとして扱います。 + +## インスタンスメソッド + +マイクロタスクのキューやサービスを使用する方法については、[マイクロタスクのガイド](/ja/docs/Web/API/HTML_DOM_API/Microtask_guide "Microtask_guide")を参照してください。 + +- {{jsxref("Promise.prototype.catch()")}} + - : プロミスに拒否ハンドラーコールバックを追加し、コールバックが呼び出されたときの返値で解決する、または、プロミスが履行された場合は、元の履行結果で解決する + 新しいプロミスを返します。 +- {{jsxref("Promise.prototype.then()")}} + - : プロミスに履行ハンドラーと拒否ハンドラーを追加し、呼び出されたハンドラーの返値で解決する新しいプロミスを返します。プロミスが処理されなかった場合 (すなわち、関連するハンドラー `onFulfilled` または `onRejected` が関数ではない場合) は、元の解決値を返します。 +- {{jsxref("Promise.prototype.finally()")}} + - : プロミスにハンドラーを追加し、元のプロミスが解決されたときに解決される新しいプロミスを返します。このハンドラーは、成功か失敗かに関わらず、元のプロミスが完了したときに呼び出されます。 + +## 例 + +### 基本的な例 + +```js +let myFirstPromise = new Promise((resolve, reject) => { + // We call resolve(...) when what we were doing asynchronously was successful, and reject(...) when it failed. + // In this example, we use setTimeout(...) to simulate async code. + // In reality, you will probably be using something like XHR or an HTML5 API. + setTimeout( function() { + resolve("Success!") // Yay! Everything went well! + }, 250) +}) + +myFirstPromise.then((successMessage) => { + // successMessage is whatever we passed in the resolve(...) function above. + // It doesn't have to be a string, but if it is only a succeed message, it probably will be. + console.log("Yay! " + successMessage) +}); +``` + +### 多様な状況に対応した例 + +この例では、プロミス機能を使用するための多様なテクニックと、発生する可能性のある多様な状況を示しています。これを理解するには、まずコードブロックの一番下までスクロールして、プロミス連鎖を調べてください。最初のプロミスが提供されてから、プロミスの連鎖が続きます。この連鎖は `.then()` の呼び出しで構成され、通常は (必ずしもそうとは限りませんが) 最後に単一の `.catch()` があり、任意で `.finally()` が続きます。この例では、プロミス連鎖は独自に書かれた `new Promise()` コンストラクターによって開始されますが、実際には、プロミス連鎖は通常、プロミスを返す API 関数 (他の誰かが書いたもの) から開始されます。 + +関数 `tetheredGetNumber()` の例では、非同期呼び出しを設定している間、またはコールバック内で、またはその両方で `reject()` を使用してプロミスを生成することを示しています。 関数 `promiseGetWord()` は、API 関数がどのように自己完結型の方法でプロミスを生成して返すかを示しています。 + +関数 `troubleWithGetNumber()` は `throw()` で終わることに注意してください。これは、 ES6 のプロミス連鎖では、エラーが発生した後で、 "throw()" がなく、エラーが "fixed" であるようにみえても、すべての `.then()` のプロミスを通過するため、強制的に行われています。これは面倒なので、 `.then()` プロミスの連鎖全体で `rejectionFunc` を省略して、最終的な `catch()` で単一の `rejectionFunc` を使用するのが一般的です。 別の方法としては、特別な値を投げるという方法があります (この場合は "-999" ですが、カスタムのエラー種別の方が適切です)。 + +このコードは NodeJS で実行できます。実際にエラーが発生しているのを見ることで理解度が高まります。より多くのエラーを強制的に発生させるには、 `threshold` の値を変更します。 + +```js +"use strict"; + +// To experiment with error handling, "threshold" values cause errors randomly +const THRESHOLD_A = 8; // can use zero 0 to guarantee error + +function tetheredGetNumber(resolve, reject) { + try { + setTimeout( + function() { + const randomInt = Date.now(); + const value = randomInt % 10; + try { + if(value >= THRESHOLD_A) { + throw new Error(`Too large: ${value}`); + } + } catch(msg) { + reject(`Error in callback ${msg}`); + } + resolve(value); + return; + }, 500); + // To experiment with error at set-up, uncomment the following 'throw'. + // throw new Error("Bad setup"); + } catch(err) { + reject(`Error during setup: ${err}`); + } + return; +} + +function determineParity(value) { + const isOdd = value % 2 ? true : false ; + const parityInfo = { theNumber: value, isOdd: isOdd }; + return parityInfo; +} + +function troubleWithGetNumber(reason) { + console.error(`Trouble getting number: ${reason}`); + throw -999; // must "throw" something, to maintain error state down the chain +} + +function promiseGetWord(parityInfo) { + // The "tetheredGetWord()" function gets "parityInfo" as closure variable. + const tetheredGetWord = function(resolve,reject) { + const theNumber = parityInfo.theNumber; + const threshold_B = THRESHOLD_A - 1; + if(theNumber >= threshold_B) { + reject(`Still too large: ${theNumber}`); + } else { + parityInfo.wordEvenOdd = parityInfo.isOdd ? 'odd' : 'even'; + resolve(parityInfo); + } + return; + } + return new Promise(tetheredGetWord); +} + +(new Promise(tetheredGetNumber)) + .then(determineParity,troubleWithGetNumber) + .then(promiseGetWord) + .then((info) => { + console.log("Got: ",info.theNumber," , ", info.wordEvenOdd); + return info; + }) + .catch((reason) => { + if(reason === -999) { + console.error("Had previously handled error"); + } + else { + console.error(`Trouble with promiseGetWord(): ${reason}`); + } + }) + .finally((info) => console.log("All done")); +``` + +<h3 id="Advanced_Example">高度な例</h3> + +以下の例は `Promise` の仕組みを示したものです。 `testPromise()` メソッドは {{HTMLElement("button")}} をクリックする度に呼び出されます。`testPromise()` メソッドは、 {{domxref("WindowOrWorkerGlobalScope.setTimeout")}} を用いて、 1 秒から 3 秒のランダムな時間の後、メソッドがこれまでに呼ばれた回数で履行されるプロミスを作成します。 `Promise()` コンストラクターを使用してプロミスを生成します。 + +プロミスが履行されたことは、 {{JSxRef("Promise.prototype.then()","p1.then()")}} で設定されたコールバックによって記録されます。この記録から、メソッドの同期処理部分が、プロミスによる非同期処理からどのように分離されているかがわかります。 + +短時間に何度もボタンをクリックすると、さまざまなプロミスが次々と履行されていく様子を見ることもできます。 + +#### HTML + +```html +<button id="make-promise">プロミスを作成</button> +<div id="log"></div> +``` + +#### JavaScript + +```js +"use strict"; +let promiseCount = 0; + +function testPromise() { + let thisPromiseCount = ++promiseCount; + let log = document.getElementById('log'); + // 開始 + log.insertAdjacentHTML('beforeend', thisPromiseCount + ') 開始<br>'); + // 新しいプロミスを作成します。このプロミスで 1 から始まる数値のカウントを (3 秒の待ち時間の後に) 約束します + let p1 = new Promise((resolve, reject) => { + // プロミスを解決または拒否する機能を持つ実行関数が呼び出されます + log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Promise コンストラクター<br>'); + // これは単に非同期にするための例に過ぎません + window.setTimeout(function() { + // プロミスを履行させます + resolve(thisPromiseCount); + }, Math.random() * 2000 + 1000); + }); + + // プロミスが解決されたときの処理を then() の呼び出しで定義します。 + // プロミスが拒否されたときの処理を catch() の呼び出しで定義しています。 + p1.then(function(val) { + // Log the fulfillment value + log.insertAdjacentHTML('beforeend', val + ') Promise 履行<br>'); + }).catch((reason) => { + // Log the rejection reason + console.log(`ここでは拒否されたプロミス (${reason}) を処理します。`); + }); + // 終了 + log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Promise 生成<br>'); +} + +if ("Promise" in window) { + let btn = document.getElementById("make-promise"); + btn.addEventListener("click",testPromise); +} else { + log = document.getElementById('log'); + log.textContent = "ブラウザーが <code>Promise<code> インターフェイスに対応していないので、実行例が利用できません。"; +} +``` + +### 結果 + +{{EmbedLiveSample("Advanced_Example", "500", "200")}} + +<h3 id="Loading_an_image_with_XHR" name="Loading_an_image_with_XHR">XHR による画像の読み込み</h3> + +`Promise` と {{domxref("XMLHttpRequest")}} で画像を読み込む別の例は、 MDN GitHub <a href="https://github.com/mdn/js-examples/tree/master/promises-test">js-examples</a> リポジトリにあり、<a href="https://mdn.github.io/js-examples/promises-test/">動作を確認する</a>ことができます。それぞれの行のコメントで Promise と XHR の構造がよくわかるはずです。 + +## 仕様書 + +{{Specifications}} + +## ブラウザーの互換性 + +{{Compat}} + +## 関連情報 + +- `Promise` のポリフィルが [`core-js`](https://github.com/zloirock/core-js#ecmascript-promise) で利用できます +- [プロミスの使用](/ja/docs/Web/JavaScript/Guide/Using_promises) +- [Promises/A+ specification](https://promisesaplus.com/) +- [Venkatraman.R - JS Promise (Part 1, Basics)](https://medium.com/@ramsunvtech/promises-of-promise-part-1-53f769245a53) +- [Venkatraman.R - JS Promise (Part 2 - Using Q.js, When.js and RSVP.js)](https://medium.com/@ramsunvtech/js-promise-part-2-q-js-when-js-and-rsvp-js-af596232525c#.dzlqh6ski) +- [Venkatraman.R - Tools for Promises Unit Testing](https://tech.io/playgrounds/11107/tools-for-promises-unittesting/introduction) +- [Jake Archibald: JavaScript Promises: There and Back Again](https://www.html5rocks.com/en/tutorials/es6/promises/) +- [Domenic Denicola: Callbacks, Promises, and Coroutines – Asynchronous Programming Patterns in JavaScript](https://de.slideshare.net/domenicdenicola/callbacks-promises-and-coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript) +- [Matt Greer: JavaScript Promises ... In Wicked Detail](https://www.mattgreer.org/articles/promises-in-wicked-detail/) +- [Forbes Lindesay: promisejs.org](https://www.promisejs.org/) +- [Speed-polyfill to polyfill both promise availability and promise performance.](https://github.com/anonyco/SPromiseMeSpeedJS/blob/master/README.md) +- [Promise polyfill](https://github.com/jakearchibald/es6-promise/) +- [Udacity: JavaScript Promises](https://www.udacity.com/course/javascript-promises--ud898) diff --git a/files/ja/web/javascript/reference/global_objects/promise/then/index.html b/files/ja/web/javascript/reference/global_objects/promise/then/index.html index c75b748aad..f0ad7223d5 100644 --- a/files/ja/web/javascript/reference/global_objects/promise/then/index.html +++ b/files/ja/web/javascript/reference/global_objects/promise/then/index.html @@ -38,7 +38,7 @@ p.then(value => { <dt><code>onFulfilled</code> {{optional_inline}}</dt> <dd><code>Promise</code> が成功したときに呼び出される {{jsxref("Function")}} です。この関数は1つの引数、 <code>fulfillment value</code> を持ちます。これが関数ではない場合は、内部的に "Identity" 関数 (受け取った引数を返す関数) に置き換えられます。</dd> <dt><code>onRejected</code> {{optional_inline}}</dt> - <dd><code>Promise</code> が拒絶されたときに呼び出される {{jsxref("Function")}} です。この関数は1つの引数、 <code>rejection reason</code> を持ちます。これが関数ではない場合は、内部的に "Thrower" 関数 (引数として受け取ったエラーを投げる関数) に置き換えられます。</dd> + <dd><code>Promise</code> が拒否されたときに呼び出される {{jsxref("Function")}} です。この関数は1つの引数、 <code>rejection reason</code> を持ちます。これが関数ではない場合は、内部的に "Thrower" 関数 (引数として受け取ったエラーを投げる関数) に置き換えられます。</dd> </dl> <h3 id="Return_value" name="Return_value">返値</h3> @@ -48,10 +48,10 @@ p.then(value => { <ul> <li>値を返した場合、 <code>then</code> によって返される Promise は返値をその値として解決します。</li> <li>何も返さなかった場合、 <code>then</code> によって返される Promise は <code>undefined</code> の値で解決します。</li> - <li>エラーを投げた場合、 <code>then</code> によって返される Promise は、その値としてエラーを投げて拒絶されます。</li> + <li>エラーを投げた場合、 <code>then</code> によって返される Promise は、その値としてエラーを投げて拒否されます。</li> <li>すでに解決している Promise を返した場合、 <code>then</code> によって返される Promise は、その Promise の値をその値として返します。</li> - <li>すでに拒絶された Promise を返した場合、 <code>then</code> によって返される Promise は、その Promise の値をその値として拒絶されます。</li> - <li>他の <strong>pending</strong> 状態の Promise オブジェクトを返した場合、 <code>then</code> によって返された Promise の解決/拒絶は、ハンドラーによって返された Promise の解決/拒絶結果に依存します。また、 <code>then</code> によって返された Promise の解決値は、ハンドラーによって返された Promise の解決値と同じになります。</li> + <li>すでに拒否された Promise を返した場合、 <code>then</code> によって返される Promise は、その Promise の値をその値として拒否されます。</li> + <li>他の <strong>pending</strong> 状態の Promise オブジェクトを返した場合、 <code>then</code> によって返された Promise の解決/拒否は、ハンドラーによって返された Promise の解決/拒否結果に依存します。また、 <code>then</code> によって返された Promise の解決値は、ハンドラーによって返された Promise の解決値と同じになります。</li> </ul> <p>以下は、 <code>then</code> メソッドの非同期性を示す例です。</p> @@ -161,7 +161,7 @@ p2.then(function(value) { }); </pre> -<p><code>then</code> の引数として渡した関数が拒絶された Promise を返した場合や、例外 (エラー) が発生した場合は、拒絶された Promise を返します。</p> +<p><code>then</code> の引数として渡した関数が拒否された Promise を返した場合や、例外 (エラー) が発生した場合は、拒否された Promise を返します。</p> <pre class="brush: js notranslate">Promise.resolve() .then(() => { @@ -174,7 +174,7 @@ p2.then(function(value) { console.error('onRejected function called: ' + error.message); });</pre> -<p>その他の場合はすべて、<ruby>解決中<rp> (</rp><rt>resolving</rt><rp>) </rp></ruby>の Promise が返されます。次の例では、チェーン上の以前の Promise が拒絶されていても、最初の <code>then()</code> は解決中の Promise に含まれた <code>42</code> を返します。</p> +<p>その他の場合はすべて、<ruby>解決中<rp> (</rp><rt>resolving</rt><rp>) </rp></ruby>の Promise が返されます。次の例では、チェーン上の以前の Promise が拒否されていても、最初の <code>then()</code> は解決中の Promise に含まれた <code>42</code> を返します。</p> <pre class="brush: js notranslate">Promise.reject() .then(() => 99, () => 42) // onRejected returns 42 which is wrapped in a resolving Promise diff --git a/files/ja/web/javascript/reference/global_objects/webassembly/compilestreaming/index.html b/files/ja/web/javascript/reference/global_objects/webassembly/compilestreaming/index.html deleted file mode 100644 index e3048ea38f..0000000000 --- a/files/ja/web/javascript/reference/global_objects/webassembly/compilestreaming/index.html +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: WebAssembly.compileStreaming() -slug: Web/JavaScript/Reference/Global_Objects/WebAssembly/compileStreaming -translation_of: Web/JavaScript/Reference/Global_Objects/WebAssembly/compileStreaming ---- -<div>{{JSRef}} {{SeeCompatTable}}</div> - -<p><strong><code>WebAssembly.compileStreaming()</code></strong> 関数はソースのストリームから直接 {{jsxref("WebAssembly.Module")}} にコンパイルします。この関数はモジュールをインスタンス化する前にコンパイルする必要がある場合に役立ちます (そうでない場合は、{{jsxref("WebAssembly.instantiateStreaming()")}} 関数の仕様が推奨されます)。</p> - -<h2 id="構文">構文</h2> - -<pre class="syntaxbox">Promise<WebAssembly.Module> WebAssembly.compileStreaming(<em>source</em>);</pre> - -<h3 id="パラメータ">パラメータ</h3> - -<dl> - <dt><em>source</em></dt> - <dd>ストリーム、コンパイルする .wasm モジュールのソースコードを表す {{domxref("Response")}} オブジェクトか、それを fulfill するプロミス。 </dd> -</dl> - -<h3 id="戻り値">戻り値</h3> - -<p>解決時にコンパイルされたモジュールを表す {{jsxref("WebAssembly.Module")}} を渡す <code>Promise</code> 。</p> - -<h3 id="例外">例外</h3> - -<ul> - <li><code>bufferSource</code> が <a href="/ja/docs/Web/JavaScript/Typed_arrays">型付き配列</a> でない場合、 {{jsxref("TypeError")}} がスローされます。</li> - <li>失敗した場合、プロミスは {{jsxref("WebAssembly.CompileError")}} を持って棄却されます。</li> -</ul> - -<h2 id="例">例</h2> - -<p>次の例 (Github上のデモ <a href="https://github.com/mdn/webassembly-examples/blob/master/js-api-examples/compile-streaming.html">compile-streaming.html</a> と、<a href="https://mdn.github.io/webassembly-examples/js-api-examples/compile-streaming.html">動作例</a> を参照してください) では、ソースから直接 .wasm モジュールをストリームして、 {{jsxref("WebAssembly.Module")}} オブジェクトにコンパイルしています。<code>compileStreaming()</code> 関数は {{domxref("Response")}} オブジェクトを渡すプロミスを受け取るので、直接 {{domxref("WindowOrWorkerGlobalScope.fetch()")}} の呼び出し結果を渡すことができます。</p> - -<pre class="brush: js">var importObject = { imports: { imported_func: arg => console.log(arg) } }; - -WebAssembly.compileStreaming(fetch('simple.wasm')) -.then(module => WebAssembly.instantiate(module, importObject)) -.then(instance => instance.exports.exported_func());</pre> - -<p>結果として受け取ったモジュールインスタンスはその後 {{jsxref("WebAssembly.instantiate()")}} を使用してインスタンス化され、エクスポートされた関数が実行されます。</p> - -<h2 id="仕様">仕様</h2> - -<table class="standard-table"> - <thead> - <tr> - <th scope="col">Specification</th> - <th scope="col">Status</th> - <th scope="col">Comment</th> - </tr> - </thead> - <tbody> - <tr> - <td>{{SpecName('WebAssembly Embedding', '#webassemblycompilestreaming', 'compileStreaming()')}}</td> - <td>{{Spec2('WebAssembly Embedding')}}</td> - <td>初回ドラフト定義</td> - </tr> - </tbody> -</table> - -<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザ実装状況</h2> - -<div> - - -<p>{{Compat("javascript.builtins.WebAssembly.compileStreaming")}}</p> -</div> - -<h2 id="関連情報">関連情報</h2> - -<ul> - <li><a href="/ja/docs/WebAssembly">WebAssembly</a> overview page</li> - <li><a href="/ja/docs/WebAssembly/Concepts">WebAssemblyのコンセプト</a></li> - <li><a href="/ja/docs/WebAssembly/Using_the_JavaScript_API">WebAssembly JavaScript APIを使用する</a></li> -</ul> diff --git a/files/ja/web/javascript/reference/global_objects/webassembly/compilestreaming/index.md b/files/ja/web/javascript/reference/global_objects/webassembly/compilestreaming/index.md new file mode 100644 index 0000000000..958c517cad --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/webassembly/compilestreaming/index.md @@ -0,0 +1,69 @@ +--- +title: WebAssembly.compileStreaming() +slug: Web/JavaScript/Reference/Global_Objects/WebAssembly/compileStreaming +tags: + - API + - JavaScript + - Method + - Object + - Reference + - WebAssembly + - compile + - compileStreaming + - streaming +browser-compat: javascript.builtins.WebAssembly.compileStreaming +translation_of: Web/JavaScript/Reference/Global_Objects/WebAssembly/compileStreaming +--- +{{JSRef}} + +**`WebAssembly.compileStreaming()`** 関数は {{jsxref("WebAssembly.Module")}} を直接、基礎的なソースのストリームからコンパイルします。この関数はモジュールをインスタンス化する前にコンパイルする必要がある場合に役立ちます (そうでない場合は、{{jsxref("WebAssembly.instantiateStreaming()")}} 関数の仕様が推奨されます)。 + +## 構文 + +```js +WebAssembly.compileStreaming(source) +``` + +### 引数 + +- _source_ + - : ストリーム、コンパイルする .wasm モジュールのソースコードを表す [`Response`](/ja/docs/Web/API/Response "Response は Fetch API のインターフェイスで、リクエストのレスポンスを表します。") オブジェクトか、それを満足するプロミスです。 + +### 返値 + +`Promise` で、コンパイルされたモジュールを表す {{jsxref("WebAssembly.Module")}} に解決します。</p> + +### 例外 + +- `bufferSource` が[型付き配列](/ja/docs/Web/JavaScript/Typed_arrays)でない場合、 {{jsxref("TypeError")}} が発生します。 +- 失敗した場合、プロミスは {{jsxref("WebAssembly.CompileError")}} をで棄却されます。 + +## 例 + +### ストリーミングのコンパイル + +次の例 (Github上のデモ [compile-streaming.html](https://github.com/mdn/webassembly-examples/blob/master/js-api-examples/compile-streaming.html) と、[動作例](https://mdn.github.io/webassembly-examples/js-api-examples/compile-streaming.html)を参照してください) では、ソースから直接 .wasm モジュールをストリームして、 {{jsxref("WebAssembly.Module")}} オブジェクトにコンパイルしています。`compileStreaming()` 関数は [`Response`](/ja/docs/Web/API/Response "Response は Fetch API のインターフェイスで、リクエストのレスポンスを表します。") オブジェクトを渡すプロミスを受け取るので、直接 {{domxref("WindowOrWorkerGlobalScope.fetch()")}} の呼び出し結果を渡すことができます。 + +```js +var importObject = { imports: { imported_func: arg => console.log(arg) } }; + +WebAssembly.compileStreaming(fetch('simple.wasm')) +.then(module => WebAssembly.instantiate(module, importObject)) +.then(instance => instance.exports.exported_func()); +``` + +結果として受け取ったモジュールインスタンスはその後 {{jsxref("WebAssembly.instantiate()")}} を使用してインスタンス化され、エクスポートされた関数が実行されます。 + +## 仕様書 + +{{Specifications}} + +## ブラウザーの互換性 + +{{Compat}} + +## 関連情報 + +- [WebAssembly](/ja/docs/WebAssembly) 概要ページ +- [WebAssembly の概念](/ja/docs/WebAssembly/Concepts) +- [WebAssembly JavaScript API の使用](/ja/docs/WebAssembly/Using_the_JavaScript_API) |