aboutsummaryrefslogtreecommitdiff
path: root/files
diff options
context:
space:
mode:
authorMasahiro FUJIMOTO <mfujimot@gmail.com>2021-09-12 01:52:23 +0900
committerMasahiro FUJIMOTO <mfujimot@gmail.com>2021-09-19 23:57:05 +0900
commitf72358bab2839cbc638a1adbe331ff37cafd4cd5 (patch)
treeeaca2e39220f28a0c39c7cdbe93678f4f552cf91 /files
parent68a0467b225cdcf072526490374d29a21977e8a1 (diff)
downloadtranslated-content-f72358bab2839cbc638a1adbe331ff37cafd4cd5.tar.gz
translated-content-f72358bab2839cbc638a1adbe331ff37cafd4cd5.tar.bz2
translated-content-f72358bab2839cbc638a1adbe331ff37cafd4cd5.zip
Statements/async_function を同期
- 2021/09/07 時点の英語版に同期
Diffstat (limited to 'files')
-rw-r--r--files/ja/web/javascript/reference/statements/async_function/index.html259
-rw-r--r--files/ja/web/javascript/reference/statements/async_function/index.md280
2 files changed, 280 insertions, 259 deletions
diff --git a/files/ja/web/javascript/reference/statements/async_function/index.html b/files/ja/web/javascript/reference/statements/async_function/index.html
deleted file mode 100644
index 2c708ddbc7..0000000000
--- a/files/ja/web/javascript/reference/statements/async_function/index.html
+++ /dev/null
@@ -1,259 +0,0 @@
----
-title: 非同期関数
-slug: Web/JavaScript/Reference/Statements/async_function
-tags:
- - Example
- - Function
- - JavaScript
- - Language feature
- - Statement
- - 文
- - 言語機能
- - 関数
-translation_of: Web/JavaScript/Reference/Statements/async_function
----
-<div>{{jsSidebar("Statements")}}</div>
-
-<p><span class="seoSummary"><code><strong>async function</strong></code> 宣言は、 <strong>非同期関数</strong> — {{jsxref("Global_Objects/AsyncFunction","AsyncFunction")}} オブジェクトである関数を定義します。非同期関数は<a href="/ja/docs/Web/JavaScript/EventLoop">イベントループ</a>を介して他のコードとは別に実行され、結果として暗黙の {{jsxref("Promise")}} を返します。ただし、非同期関数を使用したコードの構文および構造は、通常の同期関数と似たものになります。</span></p>
-
-<div class="noinclude">
-<p>{{jsxref("Operators/async_function", "async function 式", "", 1)}} を使用して非同期関数を定義することもできます。</p>
-</div>
-
-<div>{{EmbedInteractiveExample("pages/js/statement-async.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">async function <var>name</var>([<var>param</var>[, <var>param</var>[, ...<var>param</var>]]]) {
- <var>statements</var>
-}
-</pre>
-
-<h3 id="Parameters" name="Parameters">引数</h3>
-
-<dl>
- <dt><code><var>name</var></code></dt>
- <dd>関数名。</dd>
- <dt><code><var>param</var></code></dt>
- <dd>関数に渡す引数名。</dd>
- <dt><code><var>statements</var></code></dt>
- <dd>関数の本体を構成する文。</dd>
-</dl>
-
-<h3 id="Return_value" name="Return_value">返値</h3>
-
-<p>{{jsxref("Promise")}} で、非同期関数から返される値で解決するか、または非同期関数内の捕捉されなかった例外で拒否します。</p>
-
-<h2 id="Description" name="Description">解説</h2>
-
-<p>非同期関数は、 {{jsxref("Operators/await", "await")}} 式を含むことができます。これは非同期関数の実行を一時停止し、 <code>Promise</code> の解決を待ちます。そして非同期関数の実行を再開し、解決された値を返します。</p>
-
-<p><strong>キーワード <code>await</code> は、非同期関数の中でのみ有効です。</strong>非同期関数の外で使用した場合は {{jsxref("SyntaxError")}} となります。</p>
-
-<p>非同期関数が一時停止している間、呼び出し側の関数は実行が続きます (非同期関数から返される暗黙の Promise を受け取ります)。</p>
-
-<div class="note">
-<p><code>async</code>/<code>await</code> の目的は、 Promise を同期的に使用する動作を簡素化し、 <code>Promise</code> のグループに対して何らかの動作を実行することです。 <code>Promise</code> が構造化コールバックに似ているのと同様に、 <code>async</code>/<code>await</code> はジェネレーターと Promise を組み合わせたものに似ています。</p>
-</div>
-
-<h2 id="Examples" name="Examples">例</h2>
-
-<h3 id="Simple_example" name="Simple_example">シンプルな例</h3>
-
-<pre class="brush: js notranslate">function resolveAfter2Seconds() {
- console.log("starting slow promise")
- return new Promise(resolve =&gt; {
- setTimeout(function() {
- resolve("slow")
- console.log("slow promise is done")
- }, 2000)
- })
-}
-
-function resolveAfter1Second() {
- console.log("starting fast promise")
- return new Promise(resolve =&gt; {
- setTimeout(function() {
- resolve("fast")
- console.log("fast promise is done")
- }, 1000)
- })
-}
-
-async function sequentialStart() {
- console.log('==SEQUENTIAL START==')
-
- // 1. ここは即時実行される
- const slow = await resolveAfter2Seconds()
- console.log(slow) // 2. ここは 1. の2秒後に実行される
-
- const fast = await resolveAfter1Second()
- console.log(fast) // 3. ここは 1. の3秒後に実行される
-}
-
-async function concurrentStart() {
- console.log('==CONCURRENT START with await==');
- const slow = resolveAfter2Seconds() // 即時実行
- const fast = resolveAfter1Second() // 即時実行
-
- // 1. ここは即時実行される
- console.log(await slow) // 2. ここは 1. の2秒後に実行される
- console.log(await fast) // 3. ここは 1. の2秒後(2.の直後)に実行される
-}
-
-function concurrentPromise() {
- console.log('==CONCURRENT START with Promise.all==')
- return Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then((messages) =&gt; {
- console.log(messages[0]) // slow
- console.log(messages[1]) // fast
- })
-}
-
-async function parallel() {
- console.log('==PARALLEL with await Promise.all==')
-
- // 2つの jobs を並列に実行し両方が完了するのを待つ
- await Promise.all([
- (async()=&gt;console.log(await resolveAfter2Seconds()))(),
- (async()=&gt;console.log(await resolveAfter1Second()))()
- ])
-}
-
-// この関数はエラーハンドリングをしていません。後述の注意書きを参照してください。
-function parallelPromise() {
- console.log('==PARALLEL with Promise.then==')
- resolveAfter2Seconds().then((message)=&gt;console.log(message))
- resolveAfter1Second().then((message)=&gt;console.log(message))
-}
-
-sequentialStart() // 2秒後に "slow" をログ出力し、その1秒後に "fast" をログ出力する
-
-// 見やすくするため setTimeout で直前の処理が終わるのを待つ
-setTimeout(concurrentStart, 4000) // 2秒後に "slow" と "fast" をログ出力する
-
-// 直前の処理を待つ
-setTimeout(concurrentPromise, 7000) // concurrentStart と同様
-
-// 直前の処理を待つ
-setTimeout(parallel, 10000) // 本当に並列処理となるため1秒後に "fast" とログ出力し、その1秒後に "slow" とログ出力する
-
-// 直前の処理を待つ
-setTimeout(parallelPromise, 13000) // parallel と同様
-</pre>
-
-<h4 id="await_and_parallelism" name="await_and_parallelism">await と並列性</h4>
-
-<p><code>sequentialStart</code> では、最初の <code>await</code> のために実行が 2 秒間待機し、 2 つ目の <code>await</code> のためにさらに 1 秒間待機します。 2 つ目のタイマーは最初のタイマーが起動している間は作成されません。コードは 3 秒後に終了します。</p>
-
-<p><code>concurrentStart</code> では、両方のタイマーが作成され、両方とも <code>await</code> される、すなわち待機させられます。タイマーは同時に実行されているため、 3 秒後ではなく 2 秒後に、すなわち最も遅いタイマーにあわせて終了します。<br>
- しかし、 <code>await</code> の呼び出しは依然として逐次処理であり、これは 2 つ目の <code>await</code> が 1 つ目の終了まで待つことを意味します。このケースでは、最も速いタイマーが最も遅いタイマーのあとに処理されることになります。</p>
-
-<p>もし複数の処理を完全に並列に実行したい場合は、上記コード中の <code>parallel</code> のように <code>await Promise.all([job1(), job2()])</code> を使わなければなりません。</p>
-
-<div class="warning">
-<h4 id="asyncawait_vs_Promise.then_and_error_handling" name="asyncawait_vs_Promise.then_and_error_handling">async/await と Promise.then およびエラー処理</h4>
-
-<p>多くの非同期関数は Promise を用いて通常の関数として書くことができます。しかし <code>async</code> 関数はエラー処理において少し簡単です。</p>
-
-<p><code>concurrentStart</code>と<code>concurrentPromise</code>のどちらも関数としては同値です。</p>
-
-<ul>
- <li><code>concurrentStart</code> では、 <code>await</code> されたいずれかの関数呼び出しが失敗すれば、例外は自動的にキャッチされ、非同期関数の実行が中断され、暗黙的に返される Promise を経由してエラーが呼び出し元へ伝えられます。</li>
- <li>同じことが Promise の場合にも起こり、関数は、関数の完了をとらえて戻ってくる <code>Promise</code> の面倒を見なければなりません。これは <code>concurrentPromise</code> では <code>Promise.all([]).then()</code> が返す Promise を <code>return</code> することを意味します。実は、この例の前のバージョンはこれをやり忘れていました!</li>
-</ul>
-
-<p>しかしながら非同期関数も誤ってエラーを飲み込んでしまうことがあります。</p>
-
-<p>上記の <code>parallel</code> という非同期関数を例にしてみましょう。もしこれが <code>Promise.all([])</code> 呼び出しの結果を <code>await</code> (もしくは <code>return</code>) しなければ、任意のエラーは伝わりません。</p>
-
-<p><code>parallelPromise</code> の例は簡潔に見えるものの、エラーをまったくハンドルしていません!同じことをするには、やはり <code>return Promise.all[()]</code> が必要になります。</p>
-</div>
-
-<h3 id="Rewriting_a_promise_chain_with_an_async_function" name="Rewriting_a_promise_chain_with_an_async_function">promise チェーンをasync function で 書き換える</h3>
-
-<p>Promise を返す API は Promise チェーンで解決され、関数を複数の部品に分割できます。次のコードを想定してください。</p>
-
-<pre class="brush: js notranslate">function getProcessedData(url) {
- return downloadData(url) // returns a promise
- .catch(e =&gt; {
- return downloadFallbackData(url) // returns a promise
- })
- .then(v =&gt; {
- return processDataInWorker(v) // returns a promise
- })
-}
-</pre>
-
-<p>次のように 1 つの <code>async</code> 関数に書き直すことができます。</p>
-
-<pre class="brush: js notranslate">async function getProcessedData(url) {
- let v
- try {
- v = await downloadData(url)
- } catch(e) {
- v = await downloadFallbackData(url)
- }
- return processDataInWorker(v)
-}
-</pre>
-
-<p>上記の例では、 <code>return</code> ステートメント上に <code>await</code> ステートメントがないことに注目してください。なぜなら、<code>async function</code> の返値は暗黙的に {{jsxref("Promise.resolve")}} でラップされているからです。</p>
-
-<div class="blockIndicator note">
-<h4 id="return_await_promiseValue_vs._return_promiseValue" name="return_await_promiseValue_vs._return_promiseValue">return await promiseValue と return promiseValue</h4>
-
-<p>返値が {{jsxref("Promise.resolve")}} で暗黙にラッピングされるとはいえ、 <code>return await promiseValue</code> が <code>return promiseValue</code> と機能的に等価である訳ではありません。</p>
-
-<p>上記のコードを以下のように書き直したと想像してください。これは <code>processDataInWorker</code> がエラーで拒否した場合に <code>null</code> を返します。</p>
-
-<pre class="brush: js notranslate">async function getProcessedData(url) {
- let v
- try {
- v = await downloadData(url)
- } catch(e) {
- v = await downloadFallbackData(url)
- }
- try {
- return await processDataInWorker(v) // Note the `return await` vs. just `return`
- } catch (e) {
- return null
- }
-}
-</pre>
-
-<p><code>return processDataInWorker(v)</code> と記述すると、 <code>processDataInWorker(v)</code> が拒否した場合に <code>null</code> に解決されるのではなく、関数が返した {{jsxref("Promise")}} が拒否されてしまいます。</p>
-
-<p>これは、 <code>return foo;</code> と <code>return await foo;</code> の微妙な違いを強調しています。 - <code>return foo</code> はすぐに <code>foo</code> を返し、 <code>foo</code> が拒否する Promise であっても例外を発生させません。 <code>return await foo</code> は、それが Promise であれば <code>foo</code> が解決するか拒否するかを待ち、拒否した場合は<strong>返す前</strong>に例外を発生させます。</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-async-function-definitions', 'async function')}}</td>
- </tr>
- </tbody>
-</table>
-
-<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2>
-
-<div>
-<p>{{Compat("javascript.statements.async_function")}}</p>
-</div>
-
-<h2 id="See_also" name="See_also">関連情報</h2>
-
-<ul>
- <li>{{jsxref("Operators/async_function", "async function expression")}}</li>
- <li>{{jsxref("AsyncFunction")}} オブジェクト</li>
- <li>{{jsxref("Operators/await", "await")}}</li>
- <li><a href="http://innolitics.com/10x/javascript-decorators-for-promise-returning-functions/">"innolitics.com" の "Decorating Async Javascript Functions"</a></li>
-</ul>
diff --git a/files/ja/web/javascript/reference/statements/async_function/index.md b/files/ja/web/javascript/reference/statements/async_function/index.md
new file mode 100644
index 0000000000..a501540198
--- /dev/null
+++ b/files/ja/web/javascript/reference/statements/async_function/index.md
@@ -0,0 +1,280 @@
+---
+title: 非同期関数
+slug: Web/JavaScript/Reference/Statements/async_function
+tags:
+ - Example
+ - 関数
+ - JavaScript
+ - 言語機能
+ - 文
+browser-compat: javascript.statements.async_function
+translation_of: Web/JavaScript/Reference/Statements/async_function
+---
+{{jsSidebar("Statements")}}
+
+非同期関数は `async` キーワードで宣言され、その中で `await` キーワードを使うことができます。 `async` および `await` キーワードを使用することで、プロミスベースの非同期の動作を、プロミスチェーンを明示的に構成する必要なく、よりすっきりとした方法で書くことができます。
+
+非同期関数は{{jsxref("Operators/async_function", "式として", "", 1)}}も定義することができます。
+
+{{EmbedInteractiveExample("pages/js/statement-async.html", "taller")}}
+
+## 構文
+
+```js
+async function name([param[, param[, ...param]]]) {
+ statements
+}
+```
+
+### 引数
+
+- `name`
+ - : 関数の名前。
+- `param`
+ - : 関数に渡す引数名。
+- `statements`
+ - : 関数の本体を構成する文。
+
+### 返値
+
+{{jsxref("Promise")}} で、非同期関数から返される値で解決するか、または非同期関数内で捕捉されなかった例外で拒否されます。
+
+## 解説
+
+非同期関数には、 {{jsxref("Operators/await", "await")}} 式を置くことができます。 await 式は返されたプロミスが履行されるか拒否されるまで実行を中断することで、プロミスを返す関数をあたかも同期しているかのように動作させます。プロミスの解決済みの値は、await 式の返値として扱われます。`async` と `await` を使用すると、非同期コードに通常の `try` / `catch` ブロックを使用することができます。
+
+> **Note:** キーワード `await` は、通常の JavaScript コード内の非同期関数内でのみ有効です。非同期関数の外で使用した場合は {{jsxref("SyntaxError")}} が発生します。
+>
+> `await` は [JavaScript モジュール](/ja/docs/Web/JavaScript/Guide/Modules)では単独で使用することができます。
+
+> **Note:** `async`/`await` の目的は、プロミスベースの API を利用するのに必要な構文を簡素化することです。 `async`/`await` の動作は、[ジェネレーター](/ja/docs/Web/JavaScript/Guide/Iterators_and_Generators)とプロミスの組み合わせに似ています。
+
+非同期関数は常にプロミスを返します。非同期関数の返値が明示的にプロミスでない場合は、暗黙的にプロミスでラップされます。
+
+例:
+
+```js
+async function foo() {
+ return 1
+}
+```
+
+これは、次のコードに似ています。
+
+```js
+function foo() {
+ return Promise.resolve(1)
+}
+```
+
+> **Note:**
+>
+> 非同期関数の返値が `Promise.resolve` にラップされているかのように動作するとしても、両者は同等ではありません。
+>
+> 与えられた値がプロミスであった場合、 `Promise.resolve` は同じ参照を返すのに対し、非同期関数は異なる*参照*を返します。
+>
+> これは、あるプロミスと非同期関数の返値が等しいかどうかをチェックする場合に問題になることがあります。
+>
+> ```js
+> const p = new Promise((res, rej) => {
+> res(1);
+> })
+>
+> async function asyncReturn() {
+> return p;
+> }
+>
+> function basicReturn() {
+> return Promise.resolve(p);
+> }
+>
+> console.log(p === basicReturn()); // true
+> console.log(p === asyncReturn()); // false
+> ```
+
+非同期関数の本体は、 await 式で分割されていると考えることができます。最上位のコードは、 (ある場合) 最初の await 式まで、それを含めて同期的に実行されます。したがって、await 式のない非同期関数は同期的に実行されます。しかし、関数本体の中に await 式がある場合、非同期関数は常に非同期に完了します。
+
+例:
+
+```js
+async function foo() {
+ await 1
+}
+```
+
+これは次のものと等価です。
+
+```js
+function foo() {
+ return Promise.resolve(1).then(() => undefined)
+}
+```
+
+それぞれの await 式の後のコードは、`.then` コールバックの中に存在すると考えることができます。このようにして、関数を再帰的に実行するたびに、プロミスチェーンが徐々に構築されていきます。返値はチェーンの最後のリンクになります。
+
+次の例では、 2 つのプロミスを連続して待ち受けます。関数 `foo` の処理は 3 段階に分かれています。
+
+1. 関数 foo の本体の最初の行は、保留中のプロミスで await 式が構成された状態で、同期的に実行されます。その後、`foo` の処理は中断され、`foo` を呼び出した関数に制御が返されます。
+2. しばらくして、最初のプロミスが履行されるか拒否されると、制御は `foo` に戻ります。 (拒否されなかった場合は) 最初のプロミスが履行された結果が await 式から返されます。ここでは `1` が `result1` に代入されます。処理は続き、2 つ目の await 式が評価されます。このときも `foo` の処理が中断され、制御が移譲されます。
+3. しばらくして、2 つ目のプロミスが履行されたか拒否されたとき、制御は `foo` に再び入ります。2 つ目のプロミスが解決した結果が 2 番目の await 式から返されます。ここでは `2` が `result2` に代入されます。制御は (もしあれば) return 式に移ります。既定の返値である `undefined` が、現在のプロミスの解決値として返されます。
+
+```js
+async function foo() {
+ const result1 = await new Promise((resolve) => setTimeout(() => resolve('1')))
+ const result2 = await new Promise((resolve) => setTimeout(() => resolve('2')))
+}
+foo()
+```
+
+ プロミスチェーンが一度に構築されないことに注意してください。プロミスチェーンは、非同期関数に制御を渡したり戻したりしながら、段階的に構築されていきます。そのため、同時並行の非同期処理を行う際には、エラー処理の動作に注意しなければなりません。
+
+例えば、以下のコードでは、プロミスチェーンの先に `.catch` ハンドラーが設定されていたとしても、未処理のプロミス拒否エラーが発生します。これは、`p1` から制御が戻るまで、`p2` がプロミスチェーンに「配線」されないためです。
+
+```js
+async function foo() {
+ const p1 = new Promise((resolve) => setTimeout(() => resolve('1'), 1000))
+ const p2 = new Promise((_,reject) => setTimeout(() => reject('2'), 500))
+  const results = [await p1, await p2] // こうしないでください。 Promise.all または Promise.allSettled を使用してください。
+}
+foo().catch(() => {}) // すべてのエラーを浅くしようとする...
+```
+
+## 例
+
+### 非同期関数と実行順
+
+```js
+function resolveAfter2Seconds() {
+ console.log("starting slow promise")
+ return new Promise(resolve => {
+ setTimeout(function() {
+ resolve("slow")
+ console.log("slow promise is done")
+ }, 2000)
+ })
+}
+
+function resolveAfter1Second() {
+ console.log("starting fast promise")
+ return new Promise(resolve => {
+ setTimeout(function() {
+ resolve("fast")
+ console.log("fast promise is done")
+ }, 1000)
+ })
+}
+
+async function sequentialStart() {
+ console.log('==SEQUENTIAL START==')
+
+ // 1. これは即時実行される
+ const slow = await resolveAfter2Seconds()
+ console.log(slow) // 2. これは 1. の 2 秒後に実行される
+
+ const fast = await resolveAfter1Second()
+ console.log(fast) // 3. これは 1. の 3 秒後に実行される
+}
+
+async function concurrentStart() {
+ console.log('==CONCURRENT START with await==');
+ const slow = resolveAfter2Seconds() // ただちにタイマーを起動
+ const fast = resolveAfter1Second() // ただちにタイマーを起動
+
+ // 1. これは即時実行される
+ console.log(await slow) // 2. これは 1. の 2 秒後に実行される
+ console.log(await fast) // 3. fast はすでに解決しているので、これは 1. の 2 秒後 (2.の直後) に実行される
+}
+
+function concurrentPromise() {
+ console.log('==CONCURRENT START with Promise.all==')
+ return Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then((messages) => {
+ console.log(messages[0]) // slow
+ console.log(messages[1]) // fast
+ })
+}
+
+async function parallel() {
+ console.log('==PARALLEL with await Promise.all==')
+
+ // 2 つの jobs を並列に実行し両方が完了するのを待つ
+ await Promise.all([
+ (async()=>console.log(await resolveAfter2Seconds()))(),
+ (async()=>console.log(await resolveAfter1Second()))()
+ ])
+}
+
+sequentialStart() // 2 秒後に "slow" をログ出力し、その 1 秒後に "fast" をログ出力する
+
+// 直前の処理を待つ
+setTimeout(concurrentStart, 4000) // 2 秒後に "slow" と "fast" をログ出力する
+
+// 直前の処理を待つ
+setTimeout(concurrentPromise, 7000) // concurrentStart と同様
+
+// 直前の処理を待つ
+setTimeout(parallel, 10000) // 本当に並列処理となるため 1 秒後に "fast" とログ出力し、その 1 秒後に "slow" とログ出力する
+```
+
+### await と並列性
+
+`sequentialStart` では、最初の `await` のために実行が 2 秒間待機し、 2 つ目の `await` のためにさらに 1 秒間待機します。 2 つ目のタイマーは最初のタイマーが起動している間は作成されません。コードは 3 秒後に終了します。
+
+`concurrentStart` では、両方のタイマーが作成され、両方とも `await` される、すなわち待機させられます。タイマーは同時に実行されているため、 3 秒後ではなく 2 秒後に、すなわち最も遅いタイマーにあわせて終了します。
+ しかし、 `await` の呼び出しは依然として逐次処理であり、これは 2 つ目の `await` が 1 つ目の終了まで待つことを意味します。このケースでは、最も速いタイマーが最も遅いタイマーのあとに処理されることになります。
+
+複数の処理を安全に並列に実行したい場合は、 [`Promise.all`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) または
+[`Promise.allSettled`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled) の呼び出しで待つ必要があります。
+
+> **Warning:** 関数 `concurrentStart` と `concurrentPromise` は機能的に同等ではありません。
+>
+> `concurrentStart` では、プロミス `fast` がプロミス `slow` の履行よりも前に拒否された場合、呼び出し元が catch 節を構成しているかどうかにかかわらず、プロミスの拒否が処理されないというエラーが発生します。
+>
+> `concurrentPromise` では、`Promise.all` がプロミスチェーンを一括して配線します。つまり、操作はプロミスの拒否の順番に関係なくすばやく失敗し、エラーは構成されたプロミスチェーン内で常に発生するため、通常の方法で捕捉することができます。
+
+### promise チェーンを非同期関数で書き換える
+
+{{jsxref("Promise")}} を返す API はプロミスチェーンを返し、関数を複数の部品に分割できます。次のコードを想定してください。
+
+```js
+function getProcessedData(url) {
+ return downloadData(url) // プロミスを返す
+ .catch(e => {
+ return downloadFallbackData(url) // プロミスを返す
+ })
+ .then(v => {
+ return processDataInWorker(v) // プロミスを返す
+ })
+}
+```
+
+次のように 1 つの非同期関数に書き換えることができます。
+
+```js
+async function getProcessedData(url) {
+ let v
+ try {
+ v = await downloadData(url)
+ } catch(e) {
+ v = await downloadFallbackData(url)
+ }
+ return processDataInWorker(v)
+}
+```
+
+二番目の例では、有効であるにもかかわらず、 `await` 文が `return` キーワードの後にないことに注意してください。非同期関数の返値は、 (この例のように) 既にプロミスでない限り、暗黙的に {{jsxref("Promise.resolve")}} でラップされるからです。
+
+## 仕様書
+
+{{Specifications}}
+
+## ブラウザーの互換性
+
+{{Compat}}
+
+## 関連情報
+
+- {{jsxref("Operators/async_function", "非同期関数式", "", 1)}}
+- {{jsxref("AsyncFunction")}} オブジェクト
+- {{jsxref("Operators/await", "await")}}
+- ["Decorating
+ Async Javascript Functions" on "innolitics.com"](https://innolitics.com/10x/javascript-decorators-for-promise-returning-functions/)