diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/ja/web/javascript/reference/global_objects/promise | |
parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip |
initial commit
Diffstat (limited to 'files/ja/web/javascript/reference/global_objects/promise')
11 files changed, 1960 insertions, 0 deletions
diff --git a/files/ja/web/javascript/reference/global_objects/promise/all/index.html b/files/ja/web/javascript/reference/global_objects/promise/all/index.html new file mode 100644 index 0000000000..8a3c00e020 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/promise/all/index.html @@ -0,0 +1,236 @@ +--- +title: Promise.all() +slug: Web/JavaScript/Reference/Global_Objects/Promise/all +tags: + - ECMAScript 2015 + - JavaScript + - Method + - Promise + - all + - メソッド +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/all +--- +<div>{{JSRef}}</div> + +<p><strong><code>Promise.all(<var>iterable</var>)</code></strong> メソッドは単一の {{jsxref("Promise")}} を返し、これは引数 <var>iterable</var> の中のすべての Promise が解決されるか、引数 <var>iterable</var> の中に Promise がない場合に解決されます。最初に拒否された Promise の拒否理由をもって拒否されます。</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-all.html")}}</div> + +<p class="hidden">このデモのソースファイルは GitHub リポジトリに格納されています。デモプロジェクトに協力したい場合は、 <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> をクローンしてプルリクエストを送信してください。</p> + +<h2 id="Syntax" name="Syntax">構文</h2> + +<pre class="syntaxbox">Promise.all(<var>iterable</var>);</pre> + +<h3 id="Parameters" name="Parameters">引数</h3> + +<dl> + <dt><var>iterable</var></dt> + <dd>{{jsxref("Array")}} や {{jsxref("String")}} のような<ruby><a href="/ja/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterable_protocol">反復処理可能</a><rp> (</rp><rt>iterable</rt><rp>) </rp></ruby>なオブジェクト。</dd> +</dl> + +<h3 id="Return_value" name="Return_value">返値</h3> + +<ul> + <li>渡した <var>iterable</var> が空の場合、<strong>解決済み</strong>の {{jsxref("Promise")}}。</li> + <li>渡した <var>iterable</var> に Promise がない場合、<strong>非同期に解決した</strong> {{jsxref("Promise")}}。ただし、 Google Chrome 58 ではこの場合。<strong>すでに解決した</strong> Promise を返す。</li> + <li>その他の場合は<strong>待ち状態</strong>の {{jsxref("Promise")}} 。この返却される promise は次に、 <var>iterable</var> として与えられたすべての Promise が解決するか、すべての Promise が拒否されると<strong>非同期に</strong> (スタックが空になるとすぐに) 解決/拒否されます。以下の「Promise.all の非同期性・同期性」の例を見てください。返値は、実行完了の順とは関係なく、 Promise が渡された順に並びます。</li> +</ul> + +<h2 id="Description" name="Description">解説</h2> + +<p>このメソッドは複数の Promise の結果を集約するのに便利です。</p> + +<p>完成:<br> + 空の <var>iterable</var> が渡された場合、このメソッドはすでに解決した Promise を (同期的に) 返します。<br> + 渡された Promise のすべてが満たされるか、 Promise が渡されていない場合、 <code>Promise.all</code> によって返される Promise が非同期的に完成されます。<br> + すべての場合で、返された Promise は、引数として渡された <var>iterable</var> の<strong>すべての</strong>値 (Promise ではない値も) を含んだ配列で完成されます。</p> + +<p>拒否:<br> + 渡された Promise のいずれかが拒否されたら、 <code>Promise.all</code> は非同期的に、その他の Promise が完了しているかどうかに関係なく、その拒否した Promise の値で拒否されます。</p> + +<h2 id="Examples" name="Examples">例</h2> + +<h3 id="Using_Promise.all" name="Using_Promise.all"><code>Promise.all</code> の使用</h3> + +<p><code>Promise.all</code>はすべての完成 (または最初の拒否) を待ちます。</p> + +<pre class="brush: js">var p1 = Promise.resolve(3); +var p2 = 1337; +var p3 = new Promise((resolve, reject) => { + setTimeout(() => { + resolve("foo"); + }, 100); +}); + +Promise.all([p1, p2, p3]).then(values => { + console.log(values); // [3, 1337, "foo"] +});</pre> + +<p><var>iterable</var> に Promise ではない値が含まれる場合は無視されますが、 (Promise が成功する場合) 返される Promise 配列の値にはカウントされます。</p> + +<pre class="brush: js">// this will be counted as if the iterable passed is empty, so it gets fulfilled +var p = Promise.all([1,2,3]); +// this will be counted as if the iterable passed contains only the resolved promise with value "444", so it gets fulfilled +var p2 = Promise.all([1,2,3, Promise.resolve(444)]); +// this will be counted as if the iterable passed contains only the rejected promise with value "555", so it gets rejected +var p3 = Promise.all([1,2,3, Promise.reject(555)]); + +// using setTimeout we can execute code after the stack is empty +setTimeout(function() { + console.log(p); + console.log(p2); + console.log(p3); +}); + +// logs +// Promise { <state>: "fulfilled", <value>: Array[3] } +// Promise { <state>: "fulfilled", <value>: Array[4] } +// Promise { <state>: "rejected", <reason>: 555 }</pre> + +<h3 id="Promise.all_の非同期性・同期性"><code>Promise.all</code> の非同期性・同期性</h3> + +<p>以下の例では <code>Promise.all</code> の非同期性 (または渡されたiterable が空の場合、同期性) を実演します。</p> + +<pre class="brush: js">// we are passing as argument an array of promises that are already resolved, +// to trigger Promise.all as soon as possible +var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)]; + +var p = Promise.all(resolvedPromisesArray); +// immediately logging the value of p +console.log(p); + +// using setTimeout we can execute code after the stack is empty +setTimeout(function() { + console.log('the stack is now empty'); + console.log(p); +}); + +// logs, in order: +// Promise { <state>: "pending" } +// the stack is now empty +// Promise { <state>: "fulfilled", <value>: Array[2] } +</pre> + +<p><code>Promise.all</code> が拒否されたときも同じことが起きます.。</p> + +<pre class="brush: js">var mixedPromisesArray = [Promise.resolve(33), Promise.reject(44)]; +var p = Promise.all(mixedPromisesArray); +console.log(p); +setTimeout(function() { + console.log('the stack is now empty'); + console.log(p); +}); + +// logs +// Promise { <state>: "pending" } +// the stack is now empty +// Promise { <state>: "rejected", <reason>: 44 } +</pre> + +<p>しかし、<code>Promise.all</code> は渡された <var>iterable</var> が空の<strong>場合だけ</strong>同期的に解決します。</p> + +<pre class="brush: js">var p = Promise.all([]); // will be immediately resolved +var p2 = Promise.all([1337, "hi"]); // non-promise values will be ignored, but the evaluation will be done asynchronously +console.log(p); +console.log(p2) +setTimeout(function() { + console.log('the stack is now empty'); + console.log(p2); +}); + +// logs +// Promise { <state>: "fulfilled", <value>: Array[0] } +// Promise { <state>: "pending" } +// the stack is now empty +// Promise { <state>: "fulfilled", <value>: Array[2] } +</pre> + +<h3 id="Promise.all_fail-fast_behaviour" name="Promise.all_fail-fast_behaviour"><code>Promise.all</code>のフェイルファストの挙動</h3> + +<p><code>Promise.all</code> は要素のひとつでも拒否されると拒否します。例えば、タイムアウト後に4つの Promise が解決しても、1つの Promise が直ちに拒否された場合、 <code>Promise.all</code> は直ちに拒否します。</p> + +<pre class="brush: js">var p1 = new Promise((resolve, reject) => { + setTimeout(() => resolve('one'), 1000); +}); +var p2 = new Promise((resolve, reject) => { + setTimeout(() => resolve('two'), 2000); +}); +var p3 = new Promise((resolve, reject) => { + setTimeout(() => resolve('three'), 3000); +}); +var p4 = new Promise((resolve, reject) => { + setTimeout(() => resolve('four'), 4000); +}); +var p5 = new Promise((resolve, reject) => { + reject(new Error('reject')); +}); + + +// Using .catch: +Promise.all([p1, p2, p3, p4, p5]) +.then(values => { + console.log(values); +}) +.catch(error => { + console.log(error.message) +}); + +//From console: +//"reject" + +</pre> + +<p>この動作は失敗する可能性を制御することで変更することができます。</p> + +<pre class="brush: js">var p1 = new Promise((resolve, reject) => { + setTimeout(() => resolve('p1_delayed_resolvement'), 1000); +}); + +var p2 = new Promise((resolve, reject) => { + reject(new Error('p2_immediate_rejection')); +}); + +Promise.all([ + p1.catch(error => { return error }), + p2.catch(error => { return error }), +]).then(values => { + console.log(values[0]) // "p1_delayed_resolvement" + console.log(values[1]) // "Error: p2_immediate_rejection" +}) +</pre> + +<h2 id="Specifications" name="Specifications">仕様書</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">仕様書</th> + <th scope="col">状態</th> + <th scope="col">備考</th> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-promise.all', 'Promise.all')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>ECMA 標準としての初回定義</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise.all', 'Promise.all')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの対応</h2> + +<p class="hidden">互換性データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> に対してプルリクエストを書いてください。</p> + +<p>{{Compat("javascript.builtins.Promise.all")}}</p> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.race()")}}</li> +</ul> diff --git a/files/ja/web/javascript/reference/global_objects/promise/allsettled/index.html b/files/ja/web/javascript/reference/global_objects/promise/allsettled/index.html new file mode 100644 index 0000000000..83891f3857 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/promise/allsettled/index.html @@ -0,0 +1,100 @@ +--- +title: Promise.allSettled() +slug: Web/JavaScript/Reference/Global_Objects/Promise/allSettled +tags: + - JavaScript + - Method + - Promise + - Reference + - allSettled + - asynchronous + - プロミス + - メソッド + - 非同期 +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/allSettled +--- +<div>{{JSRef}}</div> + +<p><code><strong>Promise.allSettled()</strong></code> メソッドは、与えられたすべてのプロミスが満足したか拒否された後に、それぞれのプロミスの結果を記述した配列オブジェクトで解決されるプロミスを返します。</p> + +<p>一般的には、複数の非同期タスクがあり、お互いに依存せずに正常に完了する場合や、各プロミスの結果を常に知りたい場合に使用されます。</p> + +<p>これと比較して、 {{jsxref("Promise.all()")}} で返されるプロミスは、タスクがお互いに依存している場合や、タスクのいずれかが拒否されたときにすぐに拒否したい場合にはより適切かもしれません。</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-allsettled.html")}}</div> + +<h2 id="Syntax" name="Syntax">構文</h2> + +<pre class="syntaxbox notranslate"><var>Promise</var>.allSettled(<var>iterable</var>);</pre> + +<h3 id="Parameters" name="Parameters">引数</h3> + +<dl> + <dt><code><var>iterable</var></code></dt> + <dd>{{jsxref("Array")}} などの<a href="/ja/docs/Web/JavaScript/Guide/iterable">反復可能</a>オブジェクトで、それぞれの要素が <code>Promise</code> であるものです。</dd> +</dl> + +<h3 id="Return_value" name="Return_value">返値</h3> + +<p><strong>待ち状態</strong>の {{jsxref("Promise")}} で、指定されたプロミスの集合に含まれるすべてのプロミスが、正常に解決されるか拒否されるかのどちらかで完了すると、<strong>非同期に</strong>解決されます。その際、返されたプロミスのハンドラーには、元のプロミスの集合に含まれるの各プロミスの結果を含む配列が入力として渡されます。</p> + +<p>ただし、空の反復可能オブジェクトが引数として渡された<strong>場合に限り</strong>、 <code>Promise.allSettled()</code> は空の配列として<strong>解決済みの</strong> <code>Promise</code> オブジェクトを返します。</p> + +<p>出力されるそれぞれのオブジェクトには、 <code>status</code> の文字列が存在します。 status が <code>fulfilled</code> であれば、 <code>value</code> が存在します。 status が <code>rejected</code> であれば、 <code>reason</code> が存在します。 value (または reason) はそれぞれのプロミスがどの値で解決 (または拒否) されたかを反映します。</p> + +<h2 id="Examples" name="Examples">例</h2> + +<h3 id="Using_Promise.allSettled" name="Using_Promise.allSettled">Promise.allSettled の使用</h3> + +<pre class="brush: js notranslate">Promise.allSettled([ + Promise.resolve(33), + new Promise(resolve => setTimeout(() => resolve(66), 0)), + 99, + Promise.reject(new Error('an error')) +]) +.then(values => console.log(values)); + +// [ +// {status: "fulfilled", value: 33}, +// {status: "fulfilled", value: 66}, +// {status: "fulfilled", value: 99}, +// {status: "rejected", reason: Error: an error} +// ] +</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-promise.allsettled', 'Promise.allSettled')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2> + +<div class="hidden">互換性データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> に対してプルリクエストを書いてください。</div> + +<p>{{Compat("javascript.builtins.Promise.allSettled")}}</p> + +<h3 id="Implementation_Progress" name="Implementation_Progress">実装の進捗状況</h3> + +<p>以下の表は、クロスブラウザーの安定性にまだ達していないこの機能の日々の実装状況を示しています。このデータは、 JavaScript の標準テストスイートである <a href="https://github.com/tc39/test262">Test262</a> で関連する機能テストをナイトリービルド、または各ブラウザの JavaScript エンジンの最新リリースで実行することで生成されます。</p> + +<div>{{EmbedTest262ReportResultsTable("Promise.allSettled")}}</div> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li><a href="/ja/docs/Archive/Add-ons/Techniques/Promises">プロミス</a></li> + <li><a href="/ja/docs/Web/JavaScript/Guide/Using_promises">プロミスの使用</a></li> + <li><a href="/ja/docs/Learn/JavaScript/Asynchronous/Promises">プロミスを使った行儀のよい非同期のプログラミング</a></li> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.all()")}}</li> +</ul> 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 new file mode 100644 index 0000000000..bc5e1c5514 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/promise/any/index.html @@ -0,0 +1,154 @@ +--- +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> + +<div class="hidden">このページの互換性一覧表は構造化データから生成されています。データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> をチェックアウトしてプルリクエストを送信してください。</div> + +<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/catch/index.html b/files/ja/web/javascript/reference/global_objects/promise/catch/index.html new file mode 100644 index 0000000000..08ef14d5a5 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/promise/catch/index.html @@ -0,0 +1,190 @@ +--- +title: Promise.prototype.catch() +slug: Web/JavaScript/Reference/Global_Objects/Promise/catch +tags: + - ECMAScript 2015 + - JavaScript + - Method + - Promise + - Prototype +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> + +<div>{{EmbedInteractiveExample("pages/js/promise-catch.html")}}</div> + +<div class="hidden">このデモのソースファイルは GitHub リポジトリに格納されています。デモプロジェクトに協力したい場合は、 <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> をクローンしてプルリクエストを送信してください。</div> + +<h2 id="Syntax" name="Syntax">構文</h2> + +<pre class="syntaxbox notranslate"><var>p</var>.catch(<var>onRejected</var>); + +p.catch(function(<var>reason</var>) { + // rejection +}); +</pre> + +<h3 id="Parameters" name="Parameters">引数</h3> + +<dl> + <dt><code><var>onRejected</var></code></dt> + <dd><code>Promise</code> が失敗した時に呼び出される {{jsxref("Function")}} です。この関数は一つの引数を持ちます。 + <dl> + <dt><code><var>reason</var></code></dt> + <dd>拒絶された理由です。</dd> + </dl> + <code>catch()</code> で返される Promise は、 <code><var>onRejected</var></code> がエラーを発生させた場合、または返される Promise それ自体が拒絶された場合は、拒絶となります。それ以外の場合は、解決となります。</dd> +</dl> + +<h3 id="Return_value" name="Return_value">返値</h3> + +<p>内部的には、呼び出されたオブジェクトの <code>Promise.prototype.then</code> を呼び出し、引数に <code>undefined</code> と、受け取った <code><var>onRejected</var></code> ハンドラーを渡します。返値はこの呼び出しの値であり、すなわち {{jsxref("Promise")}} です。</p> + +<div class="warning"> +<p>なお、以下の例は <a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Error">Error</a> のインスタンスを投げます。これは文字列を投げる場合と比較して、良い習慣と見なされています。そうでなければ、キャッチを実行する部分で引数が string か error かをチェックする必要があり、スタックトレースのような価値のある情報を失う可能性があります。</p> +</div> + +<p><strong>内部呼び出しの例</strong></p> + +<pre class="brush: js notranslate">// overriding original Promise.prototype.then/catch just to add some logs +(function(Promise){ + var originalThen = Promise.prototype.then; + var originalCatch = Promise.prototype.catch; + + Promise.prototype.then = function(){ + console.log('> > > > > > called .then on %o with arguments: %o', this, arguments); + return originalThen.apply(this, arguments); + }; + Promise.prototype.catch = function(){ + console.error('> > > > > > called .catch on %o with arguments: %o', this, arguments); + return originalCatch.apply(this, arguments); + }; + +})(this.Promise); + + + +// calling catch on an already resolved promise +Promise.resolve().catch(function XXX(){}); + +// logs: +// > > > > > > called .catch on Promise{} with arguments: Arguments{1} [0: function XXX()] +// > > > > > > called .then on Promise{} with arguments: Arguments{2} [0: undefined, 1: function XXX()] +</pre> + +<h2 id="Description" name="Description">解説</h2> + +<p><code>catch</code> メソッドは複合したプロミスの複合のエラー処理に使用されます。これは {{jsxref("Promise")}} を返しますので、姉妹メソッドである {{jsxref("Promise.then", "then()")}} と同様の方法で<a href="/en-US/docs/Web/JavaScript/Guide/Using_promises#Chaining_after_a_catch">チェーン可能</a>です。</p> + +<h2 id="Examples" name="Examples">例</h2> + +<h3 id="Using_and_chaining_the_catch_method" name="Using_and_chaining_the_catch_method">catch メソッドの使用とチェーン化</h3> + +<pre class="brush: js notranslate">var p1 = new Promise(function(resolve, reject) { + resolve('Success'); +}); + +p1.then(function(value) { + console.log(value); // "Success!" + throw new Error('oh, no!'); +}).catch(function(e) { + console.error(e.message); // "oh, no!" +}).then(function(){ + console.log('after a catch the chain is restored'); +}, function () { + console.log('Not fired due to the catch'); +}); + +// 以下は、上記と同様に動作します +p1.then(function(value) { + console.log(value); // "Success!" + return Promise.reject('oh, no!'); +}).catch(function(e) { + console.error(e); // "oh, no!" +}).then(function(){ + console.log('after a catch the chain is restored'); +}, function () { + console.log('Not fired due to the catch'); +}); +</pre> + +<h3 id="Gotchas_when_throwing_errors" name="Gotchas_when_throwing_errors">エラーを投げたことを知る</h3> + +<pre class="brush: js notranslate">// Throwing an error will call the catch method most of the time +var p1 = new Promise(function(resolve, reject) { + throw new Error('Uh-oh!'); +}); + +p1.catch(function(e) { + console.error(e); // "Uh-oh!" +}); + +// Errors thrown inside asynchronous functions will act like uncaught errors +var p2 = new Promise(function(resolve, reject) { + setTimeout(function() { + throw new Error('Uncaught Exception!'); + }, 1000); +}); + +p2.catch(function(e) { + console.error(e); // This is never called +}); + +// Errors thrown after resolve is called will be silenced +var p3 = new Promise(function(resolve, reject) { + resolve(); + throw new Error('Silenced Exception!'); +}); + +p3.catch(function(e) { + console.error(e); // This is never called +});</pre> + +<h3 id="If_it_is_resolved" name="If_it_is_resolved">解決される場合</h3> + +<pre class="brush: js notranslate">//Create a promise which would not call onReject +var p1 = Promise.resolve("calling next"); + +var p2 = p1.catch(function (reason) { + //This is never called + console.error("catch p1!"); + console.error(reason); +}); + +p2.then(function (value) { + console.log("next promise's onFulfilled"); /* next promise's onFulfilled */ + console.log(value); /* calling next */ +}, function (reason) { + console.log("next promise's onRejected"); + console.log(reason); +});</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-promise.prototype.catch', 'Promise.prototype.catch')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2> + +<div class="hidden">互換性データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> に対してプルリクエストを書いてください。</div> + +<p>{{Compat("javascript.builtins.Promise.catch")}}</p> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.prototype.then()")}}</li> +</ul> diff --git a/files/ja/web/javascript/reference/global_objects/promise/finally/index.html b/files/ja/web/javascript/reference/global_objects/promise/finally/index.html new file mode 100644 index 0000000000..65fb7abeba --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/promise/finally/index.html @@ -0,0 +1,109 @@ +--- +title: Promise.prototype.finally() +slug: Web/JavaScript/Reference/Global_Objects/Promise/finally +tags: + - JavaScript + - Method + - Promises + - Prototype + - Reference + - finally +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/finally +--- +<div>{{JSRef}}</div> + +<p><strong><code>finally()</code></strong> メソッドは {{jsxref("Promise")}} を返します。プロミスが確立したら、満足か拒否かにかかわらず、指定されたコールバック関数が実行されます。これにより、プロミスが成功裏に実行されたか否かに関わりなく、 <code>Promise</code> が処理された後に実行されなければならないコードを提供できます。</p> + +<p>これによって、プロミスの {{jsxref("Promise.then", "then()")}} ハンドラーと {{jsxref("Promise.catch", "catch()")}} ハンドラーでコードが重複することを避けることができます。</p> + +<h2 id="Syntax" name="Syntax">構文</h2> + +<pre class="syntaxbox notranslate"><var>p</var>.finally(<var>onFinally</var>); + +<var>p</var>.finally(function() { + // 確立 (満足または拒否) +}); +</pre> + +<h3 id="Parameters" name="Parameters">引数</h3> + +<dl> + <dt><code><var>onFinally</var></code></dt> + <dd><code>Promise</code> が確立したら呼び出される {{jsxref("Function")}}。</dd> +</dl> + +<h3 id="Return_value" name="Return_value">返値</h3> + +<p><code>finally</code> ハンドラーに指定した <code>onFinally</code> が設定した {{jsxref("Promise")}} を返します。</p> + +<h2 id="Description" name="Description">解説</h2> + +<p>プロミスが確立した後、結果に関わらず何らかの処理や後始末を行いたいなら、<code>finally()</code> メソッドは役立ちます。</p> + +<p><code>finally()</code> メソッドは <code>.then(onFinally, onFinally)</code> の呼び出しとよく似ていますが、いくつかの点が異なります。</p> + +<ul> + <li>関数をインラインで作成する場合、関数を 2 度宣言するか、変数を作成するかのどちらかで、一度に渡すことができます。</li> + <li>プロミスが満足したか拒否されたかを知る術がないため、<code>finally</code> コールバックは一切引数を受け取りません。このユースケースは、拒否された理由や履行された値などを提供する必要がなく、それらを<em>気にしない</em>ときに適しています。 + <ul> + <li><code>Promise.resolve(2).then(() => {}, () => {})</code> (<code>undefined</code> で解決される) と異なり、<code>Promise.resolve(2).finally(() => {})</code> は <code>2</code> で解決される。</li> + <li>同様に、<code>Promise.reject(3).then(() => {}, () => {})</code> (<code>undefined</code> で解決される) と異なり、<code>Promise.reject(3).finally(() => {})</code> は <code>3</code> で拒否される。</li> + </ul> + </li> +</ul> + +<div class="note"> +<p><strong>補足:</strong> <code>finally</code> コールバック内で <code>throw</code> が行われた場合 (または、拒否されたプロミスを返した場合)、 <code>throw</code> を呼び出すときに指定された拒否理由と共に新しいプロミスが拒否されます。</p> +</div> + +<h2 id="Examples" name="Examples">例</h2> + +<h3 id="Using_finally" name="Using_finally">finally の使用</h3> + +<pre class="brush: js notranslate">let isLoading = true; + +fetch(myRequest).then(function(response) { + var contentType = response.headers.get("content-type"); + if(contentType && contentType.includes("application/json")) { + return response.json(); + } + throw new TypeError("Oops, we haven't got JSON!"); + }) + .then(function(json) { /* process your JSON further */ }) + .catch(function(error) { console.error(error); /* this line can also throw, e.g. when console = {} */ }) + .finally(function() { isLoading = false; }); + +</pre> + +<div class="hidden"> +<p>Please do not add polyfills on MDN pages. For more details, refer to: <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></p> +</div> + +<h2 id="Specifications" name="Specifications">仕様書</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">仕様書</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise.prototype.finally', 'Promise.prototype.finally')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2> + +<div class="hidden">互換性データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> に対してプルリクエストを書いてください。</div> + +<p>{{Compat("javascript.builtins.Promise.finally")}}</p> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.prototype.then()")}}</li> + <li>{{jsxref("Promise.prototype.catch()")}}</li> +</ul> diff --git a/files/ja/web/javascript/reference/global_objects/promise/index.html b/files/ja/web/javascript/reference/global_objects/promise/index.html new file mode 100644 index 0000000000..6a41d6a21d --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/promise/index.html @@ -0,0 +1,367 @@ +--- +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> + +<div class="hidden">互換性データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> に対してプルリクエストを書いてください。</div> + +<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/promise/index.html b/files/ja/web/javascript/reference/global_objects/promise/promise/index.html new file mode 100644 index 0000000000..816285a046 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/promise/promise/index.html @@ -0,0 +1,109 @@ +--- +title: Promise() コンストラクター +slug: Web/JavaScript/Reference/Global_Objects/Promise/Promise +tags: + - Constructor + - JavaScript + - Promise + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/Promise +--- +<div>{{JSRef}}</div> + +<p><strong><code>Promise</code></strong> コンストラクターは、主にまだプロミスに対応していない関数をラップするために使用します。</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-constructor.html", "taller")}}</div> + +<div class="hidden">このデモのソースファイルは GitHub リポジトリに格納されています。デモプロジェクトに協力したい場合は、 <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> をクローンしてプルリクエストを送信してください。</div> + +<h2 id="Syntax" name="Syntax">構文</h2> + +<pre class="syntaxbox notranslate">new Promise(<var>executor</var>) +</pre> + +<h3 id="Parameters" name="Parameters">引数</h3> + +<dl> + <dt><code><var>executor</var></code></dt> + <dd>新しい <code>Promise</code> オブジェクトを構築する過程でコンストラクターによって呼び出される {{jsxref("function")}} です。 <code><var>executor</var></code> は結果をプロミスに結びつけるカスタムコードです。プログラマーが <code><var>executor</var></code> を書きます。この関数の形式は次のようなものであると期待されます。</dd> + <dt> + <pre class="brush: js notranslate">function(<var>resolutionFunc</var>, <var>rejectionFunc</var>){ + // 通常、いくつかの非同期操作。 +} +</pre> + </dt> + <dd>コンストラクターが新しい <code>Promise</code> オブジェクトを生成するとき、 <code><var>resolutionFunc</var></code> と <code><var>rejectionFunc</var></code> の一対の関数も生成します。これらは <code>Promise</code> オブジェクトに「結束」されます。従って、 <code><var>executor</var></code> の中のコードが何らかの操作を実行し、その操作の結果を (値が別の Promise オブジェクトでない場合) 「満足」または「拒否」として、それぞれ <code><var>resolutionFunc</var></code> または <code><var>rejectionFunc</var></code> のどちらかを呼び出すことで反映する機会を持っています。</dd> + <dd><code><var>executor</var></code> は意味のある返値を持ちません。これは <code><var>resolutionFunc</var></code> または <code><var>rejectionFunc</var></code> を使用することの副作用を介して通信します。この副作用とは、 <code>Promise</code> が「解決済み」になることです。</dd> + <dd>通常は、次のように動作します。 <code><var>executor</var></code> の内部の走査は非同期であり、コールバックを提供します。コールバックは <code><var>executor</var></code> のコード内で定義されます。コールバックは、 <code><var>resolutionFunc</var></code> を呼び出すことで終了します。 <code><var>resolutionFunc</var></code> の呼び出しには、引数 <code>value</code> が含まれます。 <code>value</code> は、結束された <code>Promise</code> オブジェクトに渡されます。 <code>Promise</code> オブジェクトは (非同期的に) それに関連付けられた任意の <code>.then()</code> を呼び出します。 <code>.then()</code> によって受け取った <code>value</code> は、 <code>handleFulfilled</code> の呼び出しに入力引数として渡されます (「連鎖したプロミス」の節を参照)。</dd> + <dd>また、 <code><var>executor</var></code> はエラー時に <code><var>rejectionFunc</var></code> を呼び出す <code>try{} catch()</code> ブロックを含む可能性があります。</dd> + <dd>これらの2つの関数の呼び出し形式は単純で、あらゆる型の引数を1つだけ取ります。もちろん、これらの関数の実際の名前は好きにしてよく、すなわち、 <code><var>executor</var></code> の引数として名づけます。どちらの関数も必要な時に呼び出すために使用します。</dd> +</dl> + +<dl> + <dd> + <pre class="brush: js notranslate">resolutionFunc(value) // 満足したときに呼び出される +rejectionFunc(reason) // <em>拒否されたとき</em>に呼び出される</pre> + + <p>返される <code>value</code> は、プロミスをチェーンに動的に挿入するために、別なプロミスオブジェクトにすることができます。</p> + </dd> +</dl> + +<h3 id="Return_value" name="Return_value">返値</h3> + +<p><code>new</code> を通じて呼び出された場合、 <code>Promise</code> コンストラクターはプロミスオブジェクトを返します。このプロミスオブジェクトは、 <code><var>resolutionFunc</var></code> 関数または <code><var>rejectionFunc</var></code> 関数が呼び出されると「解決」になります。なお、 <code><var>resolutionFunc</var></code> または <code><var>rejectionFunc</var></code> を別な Promise オブジェクトを引数にして呼び出すと、これが「解決」であると言えますが、「満足」であるとは言えません。</p> + +<h2 id="Examples" name="Examples">例</h2> + +<h3 id="Creating_a_new_Promise" name="Creating_a_new_Promise">新しい Promise の作成</h3> + +<p><code>Promise</code> オブジェクトは <code>new</code> キーワードとコンストラクターで作成されます。コンストラクターは executor 関数と呼ばれる引数を取ります。 executor 関数は 2 つの関数を引数として取ります。1 つめの関数 (<code>resolve)</code> は非同期タスクが成功して完了した場合に呼び出され、タスクの結果を値として返します。2 つめの関数 (<code>reject</code>) はタスクが失敗した場合に呼び出され、失敗した理由 (典型的には error オブジェクト) を返します。</p> + +<pre class="brush: js; notranslate">const myFirstPromise = new Promise((resolve, reject) => { + // do something asynchronous which eventually calls either: + // + // resolve(someValue) // fulfilled + // or + // reject("failure reason") // rejected +}); +</pre> + +<h3 id="Making_functions_return_a_Promise" name="Making_functions_return_a_Promise">Promise を返す関数の作成</h3> + +<p>関数に Promise 機能を提供するには、次のように単に Promise を返すようにします。</p> + +<pre class="brush: js; notranslate">function myAsyncFunction(url) { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest() + xhr.open("GET", url) + xhr.onload = () => resolve(xhr.responseText) + xhr.onerror = () => reject(xhr.statusText) + xhr.send() + }); +}</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-promise-constructor', 'Promise コンストラクター')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2> + +<div class="hidden">互換性データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> に対してプルリクエストを書いてください。</div> + +<p>{{Compat("javascript.builtins.Promise.Promise")}}</p> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li><a href="/ja/docs/Web/JavaScript/Guide/Using_promises">Promise の使用</a></li> +</ul> diff --git a/files/ja/web/javascript/reference/global_objects/promise/race/index.html b/files/ja/web/javascript/reference/global_objects/promise/race/index.html new file mode 100644 index 0000000000..1ca06d96da --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/promise/race/index.html @@ -0,0 +1,182 @@ +--- +title: Promise.race() +slug: Web/JavaScript/Reference/Global_Objects/Promise/race +tags: + - ECMAScript 2015 + - JavaScript + - Method + - Promise + - Reference + - メソッド +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/race +--- +<div>{{JSRef}}</div> + +<p><code><strong>Promise.race()</strong></code> メソッドは、反復可能オブジェクトの中の Promise のうちの1つが解決または拒否するとすぐに、その Promise の値または理由で解決または拒否する Promise を返します。</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-race.html", "taller")}}</div> + +<div class="hidden">このデモのソースファイルは GitHub リポジトリに格納されています。デモプロジェクトに協力したい場合は、 <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> をクローンしてプルリクエストを送信してください。</div> + +<h2 id="Syntax" name="Syntax">構文</h2> + +<pre class="syntaxbox notranslate">Promise.race(<var>iterable</var>);</pre> + +<h3 id="Parameters" name="Parameters">引数</h3> + +<dl> + <dt><code>iterable</code></dt> + <dd>{{jsxref("Array")}} のような反復可能なオブジェクト。 <a href="/ja/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterable_protocol">iterable</a> を確認してください。</dd> +</dl> + +<h3 id="Return_value" name="Return_value">返値</h3> + +<p><strong>待ち状態の</strong> {{jsxref("Promise")}} で、反復可能オブジェクトの中で最初に解決または拒否した Promise の値を<strong>非同期に</strong>産出します。</p> + +<h2 id="Description" name="Description">説明</h2> + +<p><code>race</code> 関数は、引数として渡された反復可能オブジェクトの中にある複数の Promise の中で解決する最初の Promise と同じ方法で解決される (同じ値を取る) Promise を返します。</p> + +<p>渡された反復可能オブジェクトが空の場合、返される Promise はずっと待ち状態のままです。</p> + +<p>反復可能オブジェクトに1つ以上の Promise 以外の値やすでに解決済みの Promise が含まれていた場合、 <code>Promise.race</code> は反復可能オブジェクトの中で見つけたこれらの値の内の最初の一つで解決します。</p> + +<h2 id="Examples" name="Examples">例</h2> + +<h3 id="Asynchronicity_of_Promise.race" name="Asynchronicity_of_Promise.race">Promise.race の非同期性</h3> + +<p>以下の例は、 <code>Promise.race</code> の非同期性を示しています。</p> + +<pre class="brush: js notranslate">// we are passing as argument an array of promises that are already resolved, +// to trigger Promise.race as soon as possible +var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)]; + +var p = Promise.race(resolvedPromisesArray); +// immediately logging the value of p +console.log(p); + +// using setTimeout we can execute code after the stack is empty +setTimeout(function(){ + console.log('the stack is now empty'); + console.log(p); +}); + +// logs, in order: +// Promise { <state>: "pending" } +// the stack is now empty +// Promise { <state>: "fulfilled", <value>: 33 }</pre> + +<p>空の反復可能オブジェクトを渡すと、無限に解決しない Promise が返されます。</p> + +<pre class="brush: js notranslate">var foreverPendingPromise = Promise.race([]); +console.log(foreverPendingPromise); +setTimeout(function(){ + console.log('the stack is now empty'); + console.log(foreverPendingPromise); +}); + +// logs, in order: +// Promise { <state>: "pending" } +// the stack is now empty +// Promise { <state>: "pending" } +</pre> + +<p>反復可能オブジェクトの中に1つ以上の Promise 以外の値や、すでに解決した Promise が含まれていると、 <code>Promise.race</code> は配列の中で見つかった最初のこれらの値で解決します。</p> + +<pre class="brush: js notranslate">var foreverPendingPromise = Promise.race([]); +var alreadyFulfilledProm = Promise.resolve(100); + +var arr = [foreverPendingPromise, alreadyFulfilledProm, "non-Promise value"]; +var arr2 = [foreverPendingPromise, "non-Promise value", Promise.resolve(100)]; +var p = Promise.race(arr); +var p2 = Promise.race(arr2); + +console.log(p); +console.log(p2); +setTimeout(function(){ + console.log('the stack is now empty'); + console.log(p); + console.log(p2); +}); + +// logs, in order: +// Promise { <state>: "pending" } +// Promise { <state>: "pending" } +// the stack is now empty +// Promise { <state>: "fulfilled", <value>: 100 } +// Promise { <state>: "fulfilled", <value>: "non-Promise value" } +</pre> + +<h3 id="Promise.race_の使用_–_setTimeout_を使用した例">Promise.race の使用 – setTimeout を使用した例</h3> + +<pre class="brush: js notranslate">var p1 = new Promise(function(resolve, reject) { + setTimeout(() => resolve('one'), 500); +}); +var p2 = new Promise(function(resolve, reject) { + setTimeout(() => resolve('two'), 100); +}); + +Promise.race([p1, p2]) +.then(function(value) { + console.log(value); // "two" + // Both fulfill, but p2 is faster +}); + +var p3 = new Promise(function(resolve, reject) { + setTimeout(() => resolve('three'), 100); +}); +var p4 = new Promise(function(resolve, reject) { + setTimeout(() => reject(new Error('four')), 500); +}); + +Promise.race([p3, p4]) +.then(function(value) { + console.log(value); // "three" + // p3 is faster, so it fulfills +}, function(reason) { + // Not called +}); + +var p5 = new Promise(function(resolve, reject) { + setTimeout(() => resolve('five'), 500); +}); +var p6 = new Promise(function(resolve, reject) { + setTimeout(() => reject(new Error('six')), 100); +}); + +Promise.race([p5, p6]) +.then(function(value) { + // Not called +}, function(error) { + console.log(error.message); // "six" + // p6 is faster, so it rejects +}); +</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-promise.race', 'Promise.race')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2> + +<div class="hidden">互換性データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> に対してプルリクエストを書いてください。</div> + +<p>{{Compat("javascript.builtins.Promise.race")}}</p> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.all()")}}</li> +</ul> diff --git a/files/ja/web/javascript/reference/global_objects/promise/reject/index.html b/files/ja/web/javascript/reference/global_objects/promise/reject/index.html new file mode 100644 index 0000000000..f59d0bea93 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/promise/reject/index.html @@ -0,0 +1,74 @@ +--- +title: Promise.reject() +slug: Web/JavaScript/Reference/Global_Objects/Promise/reject +tags: + - ECMAScript 2015 + - JavaScript + - Method + - Promise + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/reject +--- +<div>{{JSRef}}</div> + +<p><strong><code>Promise.reject()</code></strong> メソッドは、引数で与えられた理由でリジェクトされた <code>Promise</code> オブジェクトを返します。</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-reject.html")}}</div> + +<div class="hidden">このデモのソースファイルは GitHub リポジトリに格納されています。デモプロジェクトに協力したい場合は、 <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> をクローンしてプルリクエストを送信してください。</div> + +<h2 id="Syntax" name="Syntax">構文</h2> + +<pre class="syntaxbox notranslate">Promise.reject(<var>reason</var>);</pre> + +<h3 id="Parameters" name="Parameters">引数</h3> + +<dl> + <dt><code><var>reason</var></code></dt> + <dd>この<code>Promise</code>オブジェクトのリジェクトされた理由</dd> +</dl> + +<h3 id="Return_value" name="Return_value">返値</h3> + +<p>与えられた理由で拒否された {{jsxref("Promise")}} 。</p> + +<h2 id="Description" name="Description">解説</h2> + +<p>静的な <code>Promise.reject</code> 関数は拒否された <code>Promise</code> を返します。デバッグのためにキャッチするエラーを選別したい場合は、 <code>reason</code> を <code>instanceof</code> {{jsxref("Error")}} にかけると良いでしょう。</p> + +<h2 id="Examples" name="Examples">例</h2> + +<h3 id="Using_the_static_Promise.reject_method" name="Using_the_static_Promise.reject_method">静的な Promise.reject() メソッドの使用</h3> + +<pre class="brush: js notranslate">Promise.reject(new Error('fail')).then(function() { + // ここは呼ばれません。 +}, function(error) { + console.error(error); // Stacktrace +});</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-promise.reject', 'Promise.reject')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2> + +<div class="hidden">互換性データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> に対してプルリクエストを書いてください。</div> + +<p>{{Compat("javascript.builtins.Promise.reject")}}</p> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> +</ul> diff --git a/files/ja/web/javascript/reference/global_objects/promise/resolve/index.html b/files/ja/web/javascript/reference/global_objects/promise/resolve/index.html new file mode 100644 index 0000000000..4584bdf8be --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/promise/resolve/index.html @@ -0,0 +1,139 @@ +--- +title: Promise.resolve() +slug: Web/JavaScript/Reference/Global_Objects/Promise/resolve +tags: + - ECMAScript 2015 + - JavaScript + - Method + - Promise + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/resolve +--- +<div>{{JSRef}}</div> + +<p><strong><code>Promise.resolve()</code></strong> メソッドは、与えられた値で解決した {{jsxref("Promise")}} オブジェクトを返します。その値がプロミスであった場合は、そのプロミスが返されます。その値が thenable (すなわち {{jsxref("Promise.then", "\"then\" メソッド")}} を持っている場合) であれば、返されるプロミスは thenable を「追跡」し、その最終的な状態を採用します。それ以外の場合は、引数で満足したプロミスが返されます。この関数は複数階層のプロミス風オブジェクト (例えば、何かで解決するプロミスで解決するプロミス) を単一の階層に平坦化します。</p> + +<h2 id="Syntax" name="Syntax">構文</h2> + +<pre class="syntaxbox notranslate">Promise.resolve(<var>value</var>); +</pre> + +<h3 id="Parameters" name="Parameters">引数</h3> + +<dl> + <dt><code><var>value</var></code></dt> + <dd>この <code>Promise</code> で解決する際の引数。解決するための <code>Promise</code> または thenable にすることもできます。</dd> +</dl> + +<h3 id="Return_value" name="Return_value">返値</h3> + +<p>与えられた値で解決された {{jsxref("Promise")}}、または value がプロミスオブジェクトであった場合、値として渡されたプロミスです。</p> + +<h2 id="Description" name="Description">解説</h2> + +<p>静的な <code>Promise.resolve</code> 関数は、解決する <code>Promise</code> を返します。</p> + +<h2 id="Examples" name="Examples">例</h2> + +<h3 id="Using_the_static_Promise.resolve_method" name="Using_the_static_Promise.resolve_method">静的な Promise.resolve メソッドの使用</h3> + +<pre class="brush: js notranslate">Promise.resolve('Success').then(function(value) { + console.log(value); // "Success" +}, function(value) { + // not called +}); +</pre> + +<h3 id="Resolving_an_array" name="Resolving_an_array">配列で解決</h3> + +<pre class="brush: js notranslate">var p = Promise.resolve([1,2,3]); +p.then(function(v) { + console.log(v[0]); // 1 +}); +</pre> + +<h3 id="Resolving_another_Promise" name="Resolving_another_Promise">別の Promise で解決</h3> + +<pre class="brush: js notranslate">var original = Promise.resolve(33); +var cast = Promise.resolve(original); +cast.then(function(value) { + console.log('value: ' + value); +}); +console.log('original === cast ? ' + (original === cast)); + +// ログの順番: +// original === cast ? true +// value: 33 +</pre> + +<p>ログの順番が反転するのは、 <code>then</code> ハンドラーが非同期に呼び出されるために発生します。 <code>then</code> がどのように動作するのかは<a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/then#Return_value">こちら</a>を参照してください。</p> + +<h3 id="Resolving_thenables_and_throwing_Errors" name="Resolving_thenables_and_throwing_Errors">thenables で解決してエラーを発生させる</h3> + +<pre class="brush: js notranslate">// Resolving a thenable object +var p1 = Promise.resolve({ + then: function(onFulfill, onReject) { onFulfill('fulfilled!'); } +}); +console.log(p1 instanceof Promise) // true, object casted to a Promise + +p1.then(function(v) { + console.log(v); // "fulfilled!" + }, function(e) { + // not called +}); + +// Thenable throws before callback +// Promise rejects +var thenable = { then: function(resolve) { + throw new TypeError('Throwing'); + resolve('Resolving'); +}}; + +var p2 = Promise.resolve(thenable); +p2.then(function(v) { + // not called +}, function(e) { + console.error(e); // TypeError: Throwing +}); + +// Thenable throws after callback +// Promise resolves +var thenable = { then: function(resolve) { + resolve('Resolving'); + throw new TypeError('Throwing'); +}}; + +var p3 = Promise.resolve(thenable); +p3.then(function(v) { + console.log(v); // "Resolving" +}, function(e) { + // not called +}); +</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-promise.resolve', 'Promise.resolve')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2> + +<div class="hidden">互換性データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> に対してプルリクエストを書いてください。</div> + +<p>{{Compat("javascript.builtins.Promise.resolve")}}</p> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> +</ul> 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 new file mode 100644 index 0000000000..323e7e874f --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/promise/then/index.html @@ -0,0 +1,300 @@ +--- +title: Promise.prototype.then() +slug: Web/JavaScript/Reference/Global_Objects/Promise/then +tags: + - ECMAScript 2015 + - JavaScript + - Method + - Promise + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/then +--- +<div>{{JSRef}}</div> + +<p><code><strong>then()</strong></code> メソッドは {{jsxref("Promise")}} を返します。最大2つの引数、 <code>Promise</code> が成功した場合と失敗した場合のコールバック関数を取ります。</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-then.html")}}</div> + +<p class="hidden">このデモのソースファイルは GitHub リポジトリに格納されています。デモプロジェクトに協力したい場合は、 <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> をクローンしてプルリクエストを送信してください。</p> + +<div class="note"> +<p>片方または両方の引数が省略されたり、関数ではないものが渡されたりした場合、 <code>then</code> にはハンドラーが不足しますが、エラーは発生しません。 <code>Promise</code> が状態 (<code>fulfillment</code> (完了) または <code>rejection</code> (拒否)) を受け入れるに当たって <code>then</code> が呼び出された際に、 <code>then</code> がハンドラーを持たない場合は、 <code>then</code> が呼び出された元の <code>Promise</code> の最後の状態を受け入れた、追加のハンドラーのない新しい <code>Promise</code> が生成されます。</p> +</div> + +<h2 id="Syntax" name="Syntax">構文</h2> + +<pre class="syntaxbox notranslate"><var>p.then(onFulfilled[, onRejected])</var>; + +p.then(value => { + // fulfillment +}, reason => { + // rejection +}); +</pre> + +<h3 id="Parameters" name="Parameters">引数</h3> + +<dl> + <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> +</dl> + +<h3 id="Return_value" name="Return_value">返値</h3> + +<p>{{jsxref("Promise")}} が完了するか拒否されると、それぞれのハンドラー関数 (<code>onFulfilled</code> または <code>onRejected</code>) が<strong>非同期に</strong>呼び出されます (現在のスレッドループにスケジュールされます)。ハンドラー関数のこの動作は特定の一連の規則に従います。もしハンドラー関数が・・・</p> + +<ul> + <li>値を返した場合、 <code>then</code> によって返される Promise は返値をその値として解決します。</li> + <li>何も返さなかった場合、 <code>then</code> によって返される Promise は <code>undefined</code> の値で解決します。</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> +</ul> + +<p>以下は、 <code>then</code> メソッドの非同期性を示す例です。</p> + +<pre class="brush: js notranslate">// using a resolved promise, the 'then' block will be triggered instantly, +// but its handlers will be triggered asynchronously as demonstrated by the console.logs +const resolvedProm = Promise.resolve(33); + +let thenProm = resolvedProm.then(value => { + console.log("this gets called after the end of the main stack. the value received and returned is: " + value); + return value; +}); +// instantly logging the value of thenProm +console.log(thenProm); + +// using setTimeout we can postpone the execution of a function to the moment the stack is empty +setTimeout(() => { + console.log(thenProm); +}); + + +// logs, in order: +// Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined} +// "this gets called after the end of the main stack. the value received and returned is: 33" +// Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 33}</pre> + +<h2 id="Description" name="Description">説明</h2> + +<p><code>then</code> メソッドや {{jsxref("Promise.prototype.catch()")}} メソッドは <code>Promise</code> を返すので、<a href="/ja/docs/Web/JavaScript/Guide/Using_promises#Chaining">チェーン可能</a>です。 — これは <em>composition</em> と呼ばれる操作です。</p> + +<h2 id="Examples" name="Examples">例</h2> + +<h3 id="Using_the_then_method" name="Using_the_then_method"><code>then</code> メソッドの使用</h3> + +<pre class="brush: js notranslate">var p1 = new Promise((resolve, reject) => { + resolve('Success!'); + // or + // reject(new Error("Error!")); +}); + +p1.then(value => { + console.log(value); // Success! +}, reason => { + console.error(reason); // Error! +} ); +</pre> + +<h3 id="Chaining" name="Chaining">チェーン</h3> + +<p><code>then</code> メソッドは <code>Promise</code> を返すので、メソッドチェーンができます。</p> + +<p>関数が <code>then</code> にハンドラーとして渡されると <code>Promise</code> を返します。同じ <code>Promise</code> がメソッドチェーンの次の <code>then</code> に現れます。次のスニペットは、非同期実行をシミュレートする、 <code>setTimeout()</code> 関数付きのコードです。</p> + +<pre class="brush: js notranslate">Promise.resolve('foo') + // 1. Receive "foo", concatenate "bar" to it, and resolve that to the next then + .then(function(string) { + return new Promise(function(resolve, reject) { + setTimeout(function() { + string += 'bar'; + resolve(string); + }, 1); + }); + }) + // 2. receive "foobar", register a callback function to work on that string + // and print it to the console, but not before returning the unworked on + // string to the next then + .then(function(string) { + setTimeout(function() { + string += 'baz'; + console.log(string); // foobarbaz + }, 1) + return string; + }) + // 3. print helpful messages about how the code in this section will be run + // before the string is actually processed by the mocked asynchronous code in the + // previous then block. + .then(function(string) { + console.log("Last Then: oops... didn't bother to instantiate and return " + + "a promise in the prior then so the sequence may be a bit " + + "surprising"); + + // Note that `string` will not have the 'baz' bit of it at this point. This + // is because we mocked that to happen asynchronously with a setTimeout function + console.log(string); // foobar + }); + +// logs, in order: +// Last Then: oops... didn't bother to instantiate and return a promise in the prior then so the sequence may be a bit surprising +// foobar +// foobarbaz</pre> + +<p><code>then()</code> の引数として渡された関数(ハンドラ)が値を返した場合は、 <code>Promise.resolve (<ハンドラーが呼ばれて返された値>) </code>によって、返値を自動的に <code>Promise</code> でラップします。</p> + +<pre class="brush: js notranslate">var p2 = new Promise(function(resolve, reject) { + resolve(1); +}); + +p2.then(function(value) { + console.log(value); // 1 + return value + 1; +}).then(function(value) { + console.log(value + ' - A synchronous value works'); // 2 - A synchronous value works +}); + +p2.then(function(value) { + console.log(value); // 1 +}); +</pre> + +<p><code>then</code> の引数として渡した関数が拒絶された Promise が返した場合や、例外 (エラー) が発生した場合は、拒絶された Promise を返します。</p> + +<pre class="brush: js notranslate">Promise.resolve() + .then(() => { + // Makes .then() return a rejected promise + throw new Error('Oh no!'); + }) + .then(() => { + console.log('Not called.'); + }, error => { + 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> + +<pre class="brush: js notranslate">Promise.reject() + .then(() => 99, () => 42) // onRejected returns 42 which is wrapped in a resolving Promise + .then(solution => console.log('Resolved with ' + solution)); // Resolved with 42</pre> + +<p>多くの場合、 <code>catch</code> を使って失敗状態の Promise を補足する方が、 <code>then</code> の 2 つのハンドラーを使って処理するよりも現実的です。下記の例を見てください。</p> + +<pre class="brush: js notranslate">Promise.resolve() + .then(() => { + // Makes .then() return a rejected promise + throw new Error('Oh no!'); + }) + .catch(error => { + console.error('onRejected function called: ' + error.message); + }) + .then(() => { + console.log("I am always called even if the prior then's promise rejects"); + });</pre> + +<p>Promise ベースの API を持った関数同士であれば、別の関数上に他の関数を実装することでチェーンを使うこともできます。</p> + +<pre class="brush: js notranslate">function fetch_current_data() { + // The <a href="/en-US/docs/Web/API/GlobalFetch/fetch">fetch</a>() API returns a Promise. This function + // exposes a similar API, except the fulfillment + // value of this function's Promise has had more + // work done on it. + return fetch('current-data.json').then(response => { + if (response.headers.get('content-type') != 'application/json') { + throw new TypeError(); + } + var j = response.json(); + // maybe do something with j + return j; // fulfillment value given to user of + // fetch_current_data().then() + }); +} +</pre> + +<p><code>onFulfilled</code> がプロミスを返した場合、 <code>then</code> の返値はプロミスによって解決/拒否されます。</p> + +<pre class="brush: js notranslate">function resolveLater(resolve, reject) { + setTimeout(function() { + resolve(10); + }, 1000); +} +function rejectLater(resolve, reject) { + setTimeout(function() { + reject(new Error('Error')); + }, 1000); +} + +var p1 = Promise.resolve('foo'); +var p2 = p1.then(function() { + // Return promise here, that will be resolved to 10 after 1 second + return new Promise(resolveLater); +}); +p2.then(function(v) { + console.log('resolved', v); // "resolved", 10 +}, function(e) { + // not called + console.error('rejected', e); +}); + +var p3 = p1.then(function() { + // Return promise here, that will be rejected with 'Error' after 1 second + return new Promise(rejectLater); +}); +p3.then(function(v) { + // not called + console.log('resolved', v); +}, function(e) { + console.error('rejected', e); // "rejected", 'Error' +}); +</pre> + +<h3 id="window.setImmediate_style_promise-based_polyfill" name="window.setImmediate_style_promise-based_polyfill">window.setImmediate 形式のプロミスベースの代替処理</h3> + +<p>{{jsxref("Function.prototype.bind()")}} を使用して、 <code>Reflect.apply</code> ({{jsxref("Reflect.apply()")}}) メソッドは (キャンセルできない) {{domxref("window.setImmediate")}} 形式の関数を作成することができます。</p> + +<pre class="brush: js notranslate">const nextTick = (() => { + const noop = () => {}; // literally + const nextTickPromise = () => Promise.resolve().then(noop); + + const rfab = Reflect.apply.bind; // (thisArg, fn, thisArg, [...args]) + const nextTick = (fn, ...args) => ( + fn !== undefined + ? Promise.resolve(args).then(rfab(null, fn, null)) + : nextTickPromise(), + undefined + ); + nextTick.ntp = nextTickPromise; + + return nextTick; +})(); +</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-promise.prototype.then', 'Promise.prototype.then')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2> + +<div class="hidden">互換性データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> に対してプルリクエストを書いてください。</div> + +<p>{{Compat("javascript.builtins.Promise.then")}}</p> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.prototype.catch()")}}</li> +</ul> |