Menu
CoddyTech

Async와 Await

Coddy Node.js 여정의 Node.js 기초 섹션에 포함된 레슨. 33개 중 23번째.

.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해야 합니다. await를 빠뜨리면 값 대신 프라미스 자체인 Promise { <pending> }을 얻게 됩니다.

challenge icon

챌린지

쉬움

이 단계에서는 Promises의 프로젝트 파일( count.js 포함)이 아니라, 강의에서 준비한 노트 명령줄 도구 프로젝트를 엽니다. 이전에 작업한 내용은 이전 강의에 그대로 남아 있습니다. store.js를 수정하기 전에 제공된 파일을 읽어 보세요. 이 사본에는 promise 기반 노트 읽기 기능과 오류 처리가 포함되어 있습니다.

이제 store.js는 readFile과 writeFile의 promise 버전을 사용하고, 메서드들은 async입니다. 하지만 아직 어떤 코드도 promise가 완료되기를 기다리지 않으므로 모든 명령이 실패합니다. 다음 단계로 넘어가기 전에 promise가 완료되어야 하는 모든 곳에 await를 추가하세요.

  1. store.js의 load에서 JSON.parse가 텍스트를 사용하기 전에 readFile이 완료되기를 기다리세요.
  2. store.js에서 load는 async이므로 promise를 반환합니다. store가 notes를 설정하는 곳에서 완료되기를 기다리세요. 모듈은 함수 바깥의 최상위 수준에서도 await를 사용할 수 있습니다.
  3. store.js의 save에서 writeFile이 완료되기를 기다리고, add와 remove에서 this.save()가 완료되기를 기다리세요.
  4. notes.js에서 이제 store.add와 store.remove는 async입니다. add 및 done 분기에서 완료되기를 기다려 n과 removed에 promise가 아닌 값이 들어가도록 하세요.

이렇게 하면 모두 합쳐 await가 일곱 개 필요합니다. 그러면 모든 명령이 이전처럼 작동합니다. list는 notes.json에 있는 노트를 보여 줍니다. 처음에 제공된 두 노트가 있을 때 add Buy bread를 실행하면 Saved note 3.이 출력되고, 이어서 done 1을 실행하면 Done: Buy milk가 출력됩니다.

직접 해 보세요: 아무것도 변경하기 전에 $ node notes.js 다음에 있는 상자에 list를 입력하세요. notes.json is damaged: ...가 표시되지만 파일은 멀쩡합니다. JSON.parse에 파일의 텍스트가 아니라 promise가 전달되었기 때문입니다. 변경한 뒤에는 list를 실행하면 노트가 다시 표시됩니다. 그런 다음 add Buy bread를 입력하고 Saved note 3.이 표시되는지 확인하세요. done 1을 입력하고 Done: Buy milk가 표시되는지 확인하세요.

직접 해보기

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

const file = 'notes.json';

// readFile과 writeFile은 이제 프로미스를 반환합니다. 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 기초의 모든 레슨

직접 연습해 보세요: Express 플레이그라운드