<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>https://mochiu.net/index.php?action=history&amp;feed=atom&amp;title=JavaScript%E3%81%AE%E5%9F%BA%E7%A4%8E_-_async_await</id>
	<title>JavaScriptの基礎 - async await - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="https://mochiu.net/index.php?action=history&amp;feed=atom&amp;title=JavaScript%E3%81%AE%E5%9F%BA%E7%A4%8E_-_async_await"/>
	<link rel="alternate" type="text/html" href="https://mochiu.net/index.php?title=JavaScript%E3%81%AE%E5%9F%BA%E7%A4%8E_-_async_await&amp;action=history"/>
	<updated>2026-04-25T23:36:53Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://mochiu.net/index.php?title=JavaScript%E3%81%AE%E5%9F%BA%E7%A4%8E_-_async_await&amp;diff=14373&amp;oldid=prev</id>
		<title>Wiki: ページの作成:「== 概要 == async / await は ES2017 (ES8) で導入された非同期処理の構文であり、Promiseをベースとして構築されている。&lt;br&gt; async関数は常にPromiseを返し、await式はPromiseの解決を待機してその値を取得する。&lt;br&gt; &lt;br&gt; async / await を使用することにより、非同期処理をまるで同期処理のように記述できる。&lt;br&gt; Promiseチェーン (.then / .catch) と比較して、コードの読みや…」</title>
		<link rel="alternate" type="text/html" href="https://mochiu.net/index.php?title=JavaScript%E3%81%AE%E5%9F%BA%E7%A4%8E_-_async_await&amp;diff=14373&amp;oldid=prev"/>
		<updated>2026-02-20T14:22:10Z</updated>

		<summary type="html">&lt;p&gt;ページの作成:「== 概要 == async / await は ES2017 (ES8) で導入された非同期処理の構文であり、Promiseをベースとして構築されている。&amp;lt;br&amp;gt; async関数は常にPromiseを返し、await式はPromiseの解決を待機してその値を取得する。&amp;lt;br&amp;gt; &amp;lt;br&amp;gt; async / await を使用することにより、非同期処理をまるで同期処理のように記述できる。&amp;lt;br&amp;gt; Promiseチェーン (.then / .catch) と比較して、コードの読みや…」&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== 概要 ==&lt;br /&gt;
async / await は ES2017 (ES8) で導入された非同期処理の構文であり、Promiseをベースとして構築されている。&amp;lt;br&amp;gt;&lt;br /&gt;
async関数は常にPromiseを返し、await式はPromiseの解決を待機してその値を取得する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
async / await を使用することにより、非同期処理をまるで同期処理のように記述できる。&amp;lt;br&amp;gt;&lt;br /&gt;
Promiseチェーン (.then / .catch) と比較して、コードの読みやすさと保守性が大幅に向上する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
エラーハンドリングには try / catch / finally構文を使用する。&amp;lt;br&amp;gt;&lt;br /&gt;
これにより、同期処理と非同期処理のエラーを統一した方法で扱うことができる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
async / await は逐次処理と並列処理の両方に対応している。&amp;lt;br&amp;gt;&lt;br /&gt;
複数の非同期処理を並列実行する場合は &amp;lt;code&amp;gt;Promise.all&amp;lt;/code&amp;gt; と組み合わせることで効率的な処理が可能になる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
ES2022以降では、ESモジュールのトップレベルでもawaitを使用できる (トップレベルawait)。&amp;lt;br&amp;gt;&lt;br /&gt;
また、非同期イテレータとの組み合わせにより &amp;lt;code&amp;gt;for await...of&amp;lt;/code&amp;gt; 構文も利用可能である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;Tauriアプリケーション開発においては、RustバックエンドとのIPC通信に &amp;lt;code&amp;gt;invoke()&amp;lt;/code&amp;gt; 関数を使用するが、この関数はPromiseを返すため、async / await との親和性が高い。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Tauri（Rust + React）では、フロントエンド（WebView）と バックエンド（Rust）間のプロセス間通信を &amp;lt;u&amp;gt;Tauri IPC&amp;lt;/u&amp;gt; と呼ぶ。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== async関数 ==&lt;br /&gt;
==== async関数の宣言 ====&lt;br /&gt;
async関数は &amp;lt;code&amp;gt;async&amp;lt;/code&amp;gt; キーワードを付与することで定義する。&amp;lt;br&amp;gt;&lt;br /&gt;
関数宣言、関数式、アロー関数、メソッド定義等、全ての関数定義形式に対応している。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // 関数宣言&lt;br /&gt;
 async function fetchData() {&lt;br /&gt;
    const response = await fetch(&amp;#039;/api/data&amp;#039;);&lt;br /&gt;
    return response.json();&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // 関数式&lt;br /&gt;
 const fetchData = async function() {&lt;br /&gt;
    const response = await fetch(&amp;#039;/api/data&amp;#039;);&lt;br /&gt;
    return response.json();&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 // アロー関数&lt;br /&gt;
 const fetchData = async () =&amp;gt; {&lt;br /&gt;
    const response = await fetch(&amp;#039;/api/data&amp;#039;);&lt;br /&gt;
    return response.json();&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 // オブジェクトメソッド&lt;br /&gt;
 const obj = {&lt;br /&gt;
    async fetchData() {&lt;br /&gt;
       const response = await fetch(&amp;#039;/api/data&amp;#039;);&lt;br /&gt;
       return response.json();&lt;br /&gt;
    }&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 // クラスメソッド&lt;br /&gt;
 class DataService {&lt;br /&gt;
    async fetchData() {&lt;br /&gt;
       const response = await fetch(&amp;#039;/api/data&amp;#039;);&lt;br /&gt;
       return response.json();&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== async関数の戻り値 ====&lt;br /&gt;
async関数の戻り値は、常にPromiseでラップされる。&amp;lt;br&amp;gt;&lt;br /&gt;
この動作はJavaScriptエンジンによって自動的に処理される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 async function example() {&lt;br /&gt;
    return 42;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 // 上記は以下と同等&lt;br /&gt;
 function example() {&lt;br /&gt;
    return Promise.resolve(42);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 example().then(value =&amp;gt; console.log(value));  // 42&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
戻り値のパターンは以下の通りである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ async関数の戻り値の変換&lt;br /&gt;
! 記述 !! 変換結果&lt;br /&gt;
|-&lt;br /&gt;
| return &amp;lt;値&amp;gt; || &amp;lt;code&amp;gt;Promise.resolve(値)&amp;lt;/code&amp;gt; に変換される&lt;br /&gt;
|-&lt;br /&gt;
| throw &amp;lt;エラー&amp;gt; || &amp;lt;code&amp;gt;Promise.reject(エラー)&amp;lt;/code&amp;gt; に変換される&lt;br /&gt;
|-&lt;br /&gt;
| return (値なし) || &amp;lt;code&amp;gt;Promise.resolve(undefined)&amp;lt;/code&amp;gt; に変換される&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 async function resolved() {&lt;br /&gt;
    return &amp;#039;success&amp;#039;;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 async function rejected() {&lt;br /&gt;
    throw new Error(&amp;#039;failure&amp;#039;);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 async function empty() {&lt;br /&gt;
    return;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 resolved().then(v =&amp;gt; console.log(v));             // &amp;quot;success&amp;quot;&lt;br /&gt;
 rejected().catch(e =&amp;gt; console.error(e.message));  // &amp;quot;failure&amp;quot;&lt;br /&gt;
 empty().then(v =&amp;gt; console.log(v));                // undefined&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== await式 ==&lt;br /&gt;
==== awaitの基本 ====&lt;br /&gt;
&amp;lt;code&amp;gt;await&amp;lt;/code&amp;gt; 式は async関数の内部でのみ使用可能である。(ES2022以降のトップレベルawaitを除く)&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;await&amp;lt;/code&amp;gt; の後にPromiseを記述することにより、そのPromiseが解決されるまで処理を一時停止し、解決値を取得する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 async function example() {&lt;br /&gt;
    // Promiseが解決されるまで待機する&lt;br /&gt;
    const value = await somePromise;&lt;br /&gt;
    console.log(value);&lt;br /&gt;
 &lt;br /&gt;
    // 非Promiseの値にもawaitは使用できる (即座に値を返す)&lt;br /&gt;
    const number = await 42;&lt;br /&gt;
    console.log(number);  // 42&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;await&amp;lt;/code&amp;gt; されたPromiseが拒否された場合、awaitの箇所で例外がスローされる。&amp;lt;br&amp;gt;&lt;br /&gt;
この例外は、try / catchで捕捉できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 async function example() {&lt;br /&gt;
    try {&lt;br /&gt;
       const value = await Promise.reject(new Error(&amp;#039;rejected&amp;#039;));&lt;br /&gt;
    }&lt;br /&gt;
    catch (error) {&lt;br /&gt;
       console.error(error.message);  // &amp;quot;rejected&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== awaitとPromiseチェーンの比較 ====&lt;br /&gt;
async / await は Promiseチェーンと同等の処理を、より読みやすい形式で記述するための構文糖衣 (Syntactic Sugar) である。&amp;lt;br&amp;gt;&lt;br /&gt;
以下に同じ処理をPromiseチェーンとasync / awaitで記述した例を示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* Promiseチェーン (Before)&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 function fetchUserData(userId) {&lt;br /&gt;
    return fetch(`/users/${userId}`)&lt;br /&gt;
       .then(response =&amp;gt; response.json())&lt;br /&gt;
       .then(user =&amp;gt; {&lt;br /&gt;
          return fetch(`/posts/${user.id}`)&lt;br /&gt;
             .then(response =&amp;gt; response.json())&lt;br /&gt;
             .then(posts =&amp;gt; ({ user, posts }));&lt;br /&gt;
       })&lt;br /&gt;
       .catch(error =&amp;gt; console.error(error));&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;br&amp;gt;&lt;br /&gt;
* async / await (After)&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 async function fetchUserData(userId) {&lt;br /&gt;
    try {&lt;br /&gt;
       const response = await fetch(`/users/${userId}`);&lt;br /&gt;
       const user = await response.json();&lt;br /&gt;
       const postsResponse = await fetch(`/posts/${user.id}`);&lt;br /&gt;
       const posts = await postsResponse.json();&lt;br /&gt;
       return { user, posts };&lt;br /&gt;
    }&lt;br /&gt;
    catch (error) {&lt;br /&gt;
       console.error(error);&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
async / await を使用することにより、ネストが解消されてソースコードのフローが上から下へ直線的に読めるようになる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;.then&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;.catch&amp;lt;/code&amp;gt; の詳細については、[[JavaScriptの基礎 - Promise]]のページを参照すること。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== エラーハンドリング ==&lt;br /&gt;
==== try / catch / finally ====&lt;br /&gt;
async関数内のエラーハンドリングには try / catch / finally 構文を使用する。&amp;lt;br&amp;gt;&lt;br /&gt;
この構文は同期処理のエラーハンドリングと同じ記法であり、直感的に理解できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 async function processData(url) {&lt;br /&gt;
    try {&lt;br /&gt;
       const response = await fetch(url);&lt;br /&gt;
       if (!response.ok) {&lt;br /&gt;
          throw new Error(`HTTP ${response.status}`);&lt;br /&gt;
       }&lt;br /&gt;
       return await response.json();&lt;br /&gt;
    }&lt;br /&gt;
    catch (error) {&lt;br /&gt;
       console.error(error.message);&lt;br /&gt;
       return null;&lt;br /&gt;
    }&lt;br /&gt;
    finally {&lt;br /&gt;
       console.log(&amp;#039;処理完了&amp;#039;);  // 成功・失敗に関わらず実行される&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
try / catch / finally の各ブロックの役割を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ try / catch / finally の各ブロックの役割&lt;br /&gt;
! ブロック !! 説明&lt;br /&gt;
|-&lt;br /&gt;
| tryブロック&lt;br /&gt;
|&lt;br /&gt;
* 正常な処理フローを記述する。&lt;br /&gt;
* await式はこのブロック内に記述する。&lt;br /&gt;
|-&lt;br /&gt;
| catchブロック&lt;br /&gt;
|&lt;br /&gt;
* エラーが発生した場合の処理を記述する。&lt;br /&gt;
* awaitされたPromiseの拒否もここで捕捉される。&lt;br /&gt;
|-&lt;br /&gt;
| finallyブロック&lt;br /&gt;
|&lt;br /&gt;
* 成功・失敗に関わらず必ず実行される処理を記述する。&lt;br /&gt;
* リソースの解放やローディング状態の解除に使用する。&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;下表に、&amp;lt;code&amp;gt;return await&amp;lt;/code&amp;gt;についての注意事項を示す。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;try / catch ブロックの内部では &amp;lt;code&amp;gt;return await&amp;lt;/code&amp;gt; を使用する必要がある。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;&amp;lt;code&amp;gt;await&amp;lt;/code&amp;gt; を省略すると、Promiseが拒否された場合にcatchブロックで捕捉できなくなるためである。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // OK : try / catch内ではreturn awaitが必要&lt;br /&gt;
 async function withErrorHandling() {&lt;br /&gt;
    try {&lt;br /&gt;
       return await riskyOperation();  // awaitが必要&lt;br /&gt;
    }&lt;br /&gt;
    catch (error) {&lt;br /&gt;
       return null;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // OK : try / catch無しの場合、awaitは不要 (余分なマイクロタスクを避けられる)&lt;br /&gt;
 async function simple() {&lt;br /&gt;
    return fetchData();  // awaitは不要&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 複数のawaitでのエラー処理 ====&lt;br /&gt;
複数のawait式が存在する場合、try / catch を1つにまとめると最初のエラーで後続の処理が中断される。&amp;lt;br&amp;gt;&lt;br /&gt;
各awaitを個別のtry / catchで囲むことで、それぞれのエラーを独立して処理できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 async function processMultiple() {&lt;br /&gt;
    let user, posts;&lt;br /&gt;
 &lt;br /&gt;
    // ユーザ取得のエラーを個別に処理する&lt;br /&gt;
    try {&lt;br /&gt;
       user = await fetchUser();&lt;br /&gt;
    }&lt;br /&gt;
    catch (error) {&lt;br /&gt;
       console.error(&amp;#039;ユーザー取得エラー:&amp;#039;, error);&lt;br /&gt;
       user = null;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    // 投稿取得のエラーを個別に処理する&lt;br /&gt;
    try {&lt;br /&gt;
       posts = await fetchPosts();&lt;br /&gt;
    }&lt;br /&gt;
    catch (error) {&lt;br /&gt;
       console.error(&amp;#039;投稿取得エラー:&amp;#039;, error);&lt;br /&gt;
       posts = [];&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    return { user, posts };&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
この方法により、ユーザ取得に失敗しても投稿取得の処理を継続できる。&amp;lt;br&amp;gt;&lt;br /&gt;
どちらのエラーも許容できない場合は、1つの try / catch にまとめてよい。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 逐次処理と並列処理 ==&lt;br /&gt;
==== 逐次実行 ====&lt;br /&gt;
await式を順番に記述すると、前のPromiseが解決されてから次のPromiseを開始する逐次実行となる。&amp;lt;br&amp;gt;&lt;br /&gt;
各処理が前の処理の結果に依存する場合は、逐次実行が適切である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 async function sequential() {&lt;br /&gt;
    // 各リクエストが完了してから次を開始する (合計: 2 + 3 + 1 = 6秒)&lt;br /&gt;
    const user = await fetch(&amp;#039;/user&amp;#039;).then(r =&amp;gt; r.json());          // 2秒&lt;br /&gt;
    const posts = await fetch(&amp;#039;/posts&amp;#039;).then(r =&amp;gt; r.json());        // 3秒&lt;br /&gt;
    const comments = await fetch(&amp;#039;/comments&amp;#039;).then(r =&amp;gt; r.json());  // 1秒&lt;br /&gt;
 &lt;br /&gt;
    return { user, posts, comments };&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 並列実行 (Promise.allとの組み合わせ) ====&lt;br /&gt;
互いに依存しない複数のPromiseは、&amp;lt;code&amp;gt;Promise.all&amp;lt;/code&amp;gt; を使用して並列実行できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Promise.all&amp;lt;/code&amp;gt; は全てのPromiseが解決されたときに解決する新しいPromiseを返す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 async function parallel() {&lt;br /&gt;
    // 全てのリクエストを同時に開始する (合計: max(2, 3, 1) = 3秒)&lt;br /&gt;
    const [user, posts, comments] = await Promise.all([&lt;br /&gt;
       fetch(&amp;#039;/user&amp;#039;).then(r =&amp;gt; r.json()),&lt;br /&gt;
       fetch(&amp;#039;/posts&amp;#039;).then(r =&amp;gt; r.json()),&lt;br /&gt;
       fetch(&amp;#039;/comments&amp;#039;).then(r =&amp;gt; r.json())&lt;br /&gt;
    ]);&lt;br /&gt;
 &lt;br /&gt;
    return { user, posts, comments };&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
並列実行では、最も時間のかかる処理が全体の待機時間を決定する。&amp;lt;br&amp;gt;&lt;br /&gt;
上記の例では、6秒から3秒へと待機時間が半減する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Promise.all&amp;lt;/code&amp;gt; はいずれかのPromiseが拒否された時点でただちに拒否される。&amp;lt;br&amp;gt;&lt;br /&gt;
全ての結果が必要な場合は &amp;lt;code&amp;gt;Promise.all&amp;lt;/code&amp;gt; を、一部の失敗を許容する場合は &amp;lt;code&amp;gt;Promise.allSettled&amp;lt;/code&amp;gt; を使用する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 注意 : awaitの連続は直列化される ====&lt;br /&gt;
&amp;lt;u&amp;gt;配列リテラル内でawaitを連続して記述すると、直列実行になってしまうため注意が必要である。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // OK : 並列実行 (全て同時に開始する)&lt;br /&gt;
 const [r1, r2, r3] = await Promise.all([promise1, promise2, promise3]);&lt;br /&gt;
 &lt;br /&gt;
 // NG : 直列実行になる (promise1 -&amp;gt; promise2 -&amp;gt; promise3 の順に待機する)&lt;br /&gt;
 const results = [await promise1, await promise2, await promise3];&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;Promise.allに渡す配列を生成する時は、Promiseオブジェクト (またはPromiseを返す関数呼び出し) を先に評価してから &amp;lt;code&amp;gt;await Promise.all()&amp;lt;/code&amp;gt; で待機する点に注意する。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== トップレベルawait ==&lt;br /&gt;
==== トップレベルawaitとは ====&lt;br /&gt;
ES2022で導入されたトップレベルawaitは、ESモジュールのトップレベル (async関数の外側) でawaitを使用できる機能である。&amp;lt;br&amp;gt;&lt;br /&gt;
これにより、モジュールの初期化処理に非同期処理を組み込むことができる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // config.mjs (ESモジュール)&lt;br /&gt;
&lt;br /&gt;
 const config = await fetch(&amp;#039;/config.json&amp;#039;).then(r =&amp;gt; r.json());&lt;br /&gt;
 &lt;br /&gt;
 export { config };&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // database.mjs&lt;br /&gt;
&lt;br /&gt;
 const db = await initializeDatabase();&lt;br /&gt;
 &lt;br /&gt;
 export async function query(sql) {&lt;br /&gt;
    return db.execute(sql);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 使用上の注意点 ====&lt;br /&gt;
下表に、トップレベルawaitを使用する時の制約と注意事項を示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ top-level awaitの使用可否&lt;br /&gt;
! 使用可否 !! 環境&lt;br /&gt;
|-&lt;br /&gt;
| 使用可能&lt;br /&gt;
|&lt;br /&gt;
* &amp;lt;u&amp;gt;.mjsファイル&amp;lt;/u&amp;gt;&lt;br /&gt;
* &amp;lt;u&amp;gt;package.jsonファイル&amp;lt;/u&amp;gt; で &amp;lt;code&amp;gt;&amp;quot;type&amp;quot;: &amp;quot;module&amp;quot;&amp;lt;/code&amp;gt; を指定した.jsファイル&lt;br /&gt;
* &amp;lt;code&amp;gt;type=&amp;quot;module&amp;quot;&amp;lt;/code&amp;gt; 属性を付与した &amp;lt;code&amp;gt;&amp;lt;script&amp;gt;&amp;lt;/code&amp;gt; タグ&lt;br /&gt;
|-&lt;br /&gt;
| 使用不可&lt;br /&gt;
|&lt;br /&gt;
* CommonJSモジュール (&amp;lt;code&amp;gt;require()&amp;lt;/code&amp;gt; 形式)&lt;br /&gt;
* &amp;lt;code&amp;gt;type=&amp;quot;module&amp;quot;&amp;lt;/code&amp;gt; のない通常の &amp;lt;code&amp;gt;&amp;lt;script&amp;gt;&amp;lt;/code&amp;gt; タグ&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;トップレベルawaitを使用するモジュールをインポートする側は、そのモジュールのawaitが解決されるまでインポートが完了しない。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;モジュールの依存関係が深い場合、初期化時間が長くなる可能性があるため注意すること。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== asyncイテレーション ==&lt;br /&gt;
==== for await...of ====&lt;br /&gt;
&amp;lt;code&amp;gt;for await...of&amp;lt;/code&amp;gt; 構文は、非同期イテラブルオブジェクトを順次処理するための構文である。&amp;lt;br&amp;gt;&lt;br /&gt;
非同期ジェネレータ関数 (&amp;lt;code&amp;gt;async function*&amp;lt;/code&amp;gt;) と組み合わせることにより、ストリーム処理やページネーション処理を直感的に記述できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 // 非同期ジェネレータ関数でページネーションを実装する&lt;br /&gt;
 async function* fetchPages(url) {&lt;br /&gt;
    let page = 1;&lt;br /&gt;
    while (true) {&lt;br /&gt;
       const response = await fetch(`${url}?page=${page}`);&lt;br /&gt;
       const data = await response.json();&lt;br /&gt;
 &lt;br /&gt;
       if (data.items.length === 0) break;&lt;br /&gt;
 &lt;br /&gt;
       for (const item of data.items) {&lt;br /&gt;
          yield item;&lt;br /&gt;
       }&lt;br /&gt;
       page++;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // for await...ofで非同期イテレータを消費する&lt;br /&gt;
 async function processAllPosts() {&lt;br /&gt;
    for await (const item of fetchPages(&amp;#039;/api/posts&amp;#039;)) {&lt;br /&gt;
       console.log(item.title);&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;for await...of&amp;lt;/code&amp;gt; は非同期ジェネレータだけでなく、&amp;lt;code&amp;gt;Symbol.asyncIterator&amp;lt;/code&amp;gt; を実装したオブジェクトにも使用できる。&amp;lt;br&amp;gt;&lt;br /&gt;
これは、Node.jsのReadableStream等、データの逐次読み取りが必要な場面で活用できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tauriでの使用例 ==&lt;br /&gt;
Tauriアプリケーションでは、&amp;lt;code&amp;gt;invoke()&amp;lt;/code&amp;gt; 関数を使用してRustバックエンドのコマンドを呼び出す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;invoke()&amp;lt;/code&amp;gt; はPromiseを返すため、async / await との組み合わせが自然である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Reactコンポーネントでの基本的な使用例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 import { useEffect, useState } from &amp;#039;react&amp;#039;;&lt;br /&gt;
 import { invoke } from &amp;#039;@tauri-apps/api/core&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 function UserList() {&lt;br /&gt;
    const [users, setUsers] = useState([]);&lt;br /&gt;
    const [loading, setLoading] = useState(false);&lt;br /&gt;
 &lt;br /&gt;
    useEffect(() =&amp;gt; {&lt;br /&gt;
       // useEffect内でasync関数を定義して即時実行する&lt;br /&gt;
       const loadUsers = async () =&amp;gt; {&lt;br /&gt;
          setLoading(true);&lt;br /&gt;
          try {&lt;br /&gt;
             const result = await invoke(&amp;#039;get_users&amp;#039;);&lt;br /&gt;
             setUsers(result);&lt;br /&gt;
          }&lt;br /&gt;
          catch (error) {&lt;br /&gt;
             console.error(error);&lt;br /&gt;
          }&lt;br /&gt;
          finally {&lt;br /&gt;
             setLoading(false);&lt;br /&gt;
          }&lt;br /&gt;
       };&lt;br /&gt;
       loadUsers();&lt;br /&gt;
    }, []);&lt;br /&gt;
 &lt;br /&gt;
    const handleDelete = async (id) =&amp;gt; {&lt;br /&gt;
       try {&lt;br /&gt;
          await invoke(&amp;#039;delete_user&amp;#039;, { id });&lt;br /&gt;
          setUsers(prev =&amp;gt; prev.filter(u =&amp;gt; u.id !== id));&lt;br /&gt;
       }&lt;br /&gt;
       catch (error) {&lt;br /&gt;
          console.error(error);&lt;br /&gt;
       }&lt;br /&gt;
    };&lt;br /&gt;
 &lt;br /&gt;
    if (loading) return &amp;lt;div&amp;gt;読み込み中...&amp;lt;/div&amp;gt;;&lt;br /&gt;
 &lt;br /&gt;
    return (&lt;br /&gt;
       &amp;lt;ul&amp;gt;&lt;br /&gt;
          {users.map(user =&amp;gt; (&lt;br /&gt;
             &amp;lt;li key={user.id}&amp;gt;&lt;br /&gt;
                {user.name}&lt;br /&gt;
                &amp;lt;button onClick={() =&amp;gt; handleDelete(user.id)}&amp;gt;削除&amp;lt;/button&amp;gt;&lt;br /&gt;
             &amp;lt;/li&amp;gt;&lt;br /&gt;
          ))}&lt;br /&gt;
       &amp;lt;/ul&amp;gt;&lt;br /&gt;
    );&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
useEffect内でasync関数を直接渡すことはできないため、内部でasync関数を定義して即時実行するパターンを使用する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
複数のTauriコマンドを並列実行する例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 async function loadInitialData() {&lt;br /&gt;
    // 複数のTauriコマンドを並列実行する&lt;br /&gt;
    const [users, settings] = await Promise.all([&lt;br /&gt;
       invoke(&amp;#039;get_users&amp;#039;),&lt;br /&gt;
       invoke(&amp;#039;get_settings&amp;#039;)&lt;br /&gt;
    ]);&lt;br /&gt;
 &lt;br /&gt;
    return { users, settings };&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
複数のTauriコマンドに依存関係がない場合は、&amp;lt;code&amp;gt;Promise.all&amp;lt;/code&amp;gt; を使用して並列実行することでパフォーマンスを向上できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 関連情報 ==&lt;br /&gt;
* [[JavaScriptの基礎 - Promise]]&lt;br /&gt;
* [[JavaScriptの基礎 - イベントループ]]&lt;br /&gt;
* [[JavaScriptの基礎 - Fetch API]]&lt;br /&gt;
* [[JavaScriptの基礎 - コールバック関数]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{#seo:&lt;br /&gt;
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki&lt;br /&gt;
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,電気回路,電子回路,基板,プリント基板&lt;br /&gt;
|description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux&lt;br /&gt;
|image=/resources/assets/MochiuLogo_Single_Blue.png&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
__FORCETOC__&lt;br /&gt;
[[カテゴリ:Web]]&lt;/div&gt;</summary>
		<author><name>Wiki</name></author>
	</entry>
</feed>