TypeScript async/await 非同期プログラミング

async/await は ES2017 で導入された非同期プログラミングの糖衣構文であり、非同期コードを同期コードのように見せることができます。

SVG 図: async/await 実行フロー 背景 タイトル async/await 実行フロー 左: Promise Promise 方式 fetchData() .then(result => { console.log(result); }) 矢印 右: async/await async/await 方式 async function main() { const result = await fetchData(); console.log(result); } 下: 実行フロー await 実行順 タイムライン メインスレッド await 一時停止 Promise バックグラウンド実行 再開 再開完了 完了 右側の説明 優位性の比較 ✓ コードがより簡潔 ✓ 同期スタイル ✓ より良いエラースタック ✓ デバッグが容易 ✓ try/catch 処理 矢印の定義

上の図は、従来の Promise と比較した async/await の利点を示しています。コードがより簡潔で、実行フローがより明確です。


Promise の基本

Promise は非同期操作の最終結果を表します。

例

// Promise を作成
var promise = new Promise(function(resolve, reject) {
    var success = true;
    if (success) {
        resolve("操作成功");
    } else {
        reject("操作失敗");
    }
});

promise.then(function(result) {
    console.log("成功: " + result);
})["catch"](function(error) {
    console.log("失敗: " + error);
});

実行結果:

成功: 操作が成功しました

async 関数

async キーワードを使用して非同期関数を宣言します。

例

// async 関数は自動的に Promise を返す
async function greet(): Promise<string> {
    return "Hello, World!";
}

greet().then(function(result) {
    console.log("結果: " + result);
});

// 非同期関数は Promise を返す
async function getData() {
    return { name: "Alice", age: 25 };
}

getData().then(function(data) {
    console.log("データ: " + JSON.stringify(data));
});

実行結果:

结果: Hello, World!
数据: {"name":"Alice","age":25}

await キーワード

await は Promise の完了を待って結果を取得します。

例

// 非同期操作をシミュレート
function delay(ms: number): Promise<string> {
    return new Promise(function(resolve) {
        setTimeout(function() {
            resolve(完了!);
        }, ms);
    });
}

async function main() {
    console.log("開始...");
    var result = await delay(100);
    console.log("結果: " + result);
    console.log("終了");
}

main();

実行結果:

開始...結果: 完了!終了

エラー処理

try/catch を使用して非同期エラーを処理します。

例

function mayFail(shouldFail: boolean): Promise<string> {
    return new Promise(function(resolve, reject) {
        if (shouldFail) {
            reject(new Error("操作失敗"));
        } else {
            resolve("操作成功");
        }
    });
}

async function handleError() {
    try {
        var result = await mayFail(true);
        console.log("結果: " + result);
    } catch (error) {
        console.log("エラー捕捉: " + error.message);
    }
}

handleError();

実行結果:

エラー捕捉: 操作失敗

並列実行

Promise.all を使用して複数の非同期操作を並列に実行します。

例

function fetchUser(id: number): Promise<{ id: number; name: string }> {
    return Promise.resolve({ id: id, name: "User" + id });
}

async function main() {
    // 直列実行
    console.time("直列");
    var user1 = await fetchUser(1);
    var user2 = await fetchUser(2);
    console.log("直列完了: " + user1.name + ", " + user2.name);
    console.timeEnd("直列");

    // 並列実行
    console.time("並列");
    var results = await Promise.all([fetchUser(1), fetchUser(2)]);
    console.log("並列完了: " + results[0].name + ", " + results[1].name);
    console.timeEnd("並列");
}

main();

実行結果:

串行完成: User1, User2
并行完成: User1, User2

async/await が Promise に比べて優れている点

  • コードがより簡潔で読みやすい
  • 同期コードスタイル
  • より良いエラースタック
  • デバッグが容易

まとめ

  • async:非同期関数の宣言
  • await:Promise を待つ
  • エラー処理:try/catch
  • 並列:Promise.all

その他の拡張