Menu
CoddyTech

AsyncとAwait

CoddyのNode.jsジャーニー「Node.jsの基礎」セクションの一部。レッスン 16/24。

.thenを連鎖させる書き方は、「読み込んでから、解析し、それから保存する」という手順の考え方とは異なる読み方になります。

async関数の中では、awaitはプロミスが確定するまで処理を一時停止し、その値を返します。プロミスが失敗するとそこで例外がスローされるため、tryとcatchで処理できます。モジュールでは、awaitはトップレベルでも使えます。

import { readFile } from 'node:fs/promises';

const loadConfig = async () => {
    try {
        return JSON.parse(await readFile('config.json', 'utf8'));
    } catch {
        return {};
    }
};

const config = await loadConfig();
console.log(config.port ?? 3000);

async関数は必ずプロミスを返すため、呼び出し元でもそれを待つ必要があります。awaitを忘れると、値ではなくプロミスそのもの、Promise { <pending> }を受け取ります。

challenge icon

チャレンジ

簡単
  • store.jsは、現在node:fs/promisesを使って読み書きします。すべてのコマンドが以前と同じように動作するよう、不足しているawaitを追加してください。
  • notes.jsは、現在asyncになっているstore.addとstore.removeをawaitします。

まずnode notes.js listを実行してエラーを読み、動作するようになったらaddとdone 1を実行してください。

自分で試してみよう

import { existsSync } from 'node:fs';
import { readFile, writeFile } from 'node:fs/promises';

const file = 'notes.json';

// readFile と writeFile は現在、Promise を返します。それぞれ await で完了を待ちます。
const load = async () => {
    if (!existsSync(file)) {
        return [];
    }
    try {
        return JSON.parse(readFile(file, 'utf8'));
    } catch (err) {
        console.error(`notes.json is damaged: ${err.message}`);
        process.exit(1);
    }
};

const store = {
    notes: load(),
    async save() {
        writeFile(file, JSON.stringify(this.notes, null, 2));
    },
    async add(text) {
        this.notes.push(text);
        this.save();
        return this.notes.length;
    },
    async remove(n) {
        const [text] = this.notes.splice(n - 1, 1);
        this.save();
        return text;
    },
};

export default store;
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

Node.jsの基礎のすべてのレッスン