https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlCfBV%2FbtrGJFIfA1Y%2FPRKYYW8W2DAJAvkJEPFG51%2Fimg.jpg
이번 장은 비동기 API를 사용하는 코드를 쉽게 작성하게 하는 Promise 클래스와 async/await 구문에 대해 살펴보자
이번 장은 노드제이에스가 제공하는 readFile과 같은 비동기 API를 예로 들고 있기 때문에 tsconfig.json 파일에 별도의 설정이 필요하다.
// tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"target": "es2015",
"moduleResolution": "node",
"outDir": "dist",
"baseUrl": ".",
"sourceMap": true,
"downlevelIteration": true, // 이 부분을 true로
"noImplicitAny": false,
"paths": { "*": ["node_modules/*"] }
},
"include": ["src/**/*"]
}
동기와 비동기 API
Node.js에서는 파일 시스템과 관련된 기능을 모아둔 fs 패키지를 제공한다. fs 패키지는 같은 기능을 동기와 비동기 버전으로 나누어 제공한다. 파일을 읽는 기능은 동기 버전인 readFileSync와 비동기 버전인 readFile로 제공한다.
먼저, src 디렉터리에 test.ts파일을 만들고 다음처럼 작성하자. test.ts 파일은 package.json 파일을 읽어 화면에 출력하는데, 이를 동기와 비동기 방식으로 구현한 예를 보여준다.
import { readFileSync, readFile } from 'fs'
// package.json 파일을 동기 방식으로 읽는 예
console.log('read package.json using synchronous api...')
const buffer: Buffer = readFileSync('./package.json')
console.log(buffer.toString())
// package.json 파일을 비동기 방식으로 읽는 예
readFile('./package.json', (error: Error, buffer: Buffer) => {
console.log('read package.json using asynchronous api...')
console.log(buffer.toString())
})
// Promise 와 async/await 구문을 사용한 예
const readFilePromise = (filename: string): Promise<string> =>
new Promise<string>((resolve, reject) => {
readFile(filename, (error: Error, buffer: Buffer) => {
if (error) reject(error)
else resolve(buffer.toString())
})
});
(async () => {
const content = await readFilePromise('./package.json')
console.log('read package.json using Promise and async/await...')
console.log(content)
})()
운영체제가 제공하는 서비스를 API라고 한다. API는 타입스크립트와 같은 프로그래밍 언어의 함수 형태로 제공된다. 그런데 API 함수는 일반 함수와 달리 하드디스크에 저장된 파일을 읽는 등 실행 시 물리적인 시간이 소요된다.
따라서 파일 내용을 모두 읽을 때까지 프로그램의 동작을 잠시 멈추는 동기 방식의 API와 프로그램의 동작을 멈추지 않는 대신 결과를 콜백 함수로 얻게 하는 비동기 방식의 API를 제공한다. 즉, 방식만 다를 뿐 똑같은 기능을 제공한다.
비동기 API의 콜백 함수를 특별히 비동기 콜백 함수라고 하낟. 일반 함수와 달리 API의 물리적인 동작 결과를 수신하는 목적으로만 사용된다.
readFileSync와 readFile API
Node.js에서 파일 읽기는 readFileSync라는 이름의 API를 사용해서 구현한다. readFileSync는 파일을 읽어서 Buffer라는 타입으로 전달해 준다.
import {readFileSync} from "fs"
readFileSync(path:string): Buffer
Buffer 는 Node.js가 제공하는 클래스로 바이너리 데이터를 저장하는 기능을 수행한다. Buffer의 데이터를 문자열로 만들려고 할 때는 Buffer의 toString 메서드를 사용하면 된다. API 이름이 “xxxSync”인 것은 모두 동기 방식으로 동작한다.
다음 코드는 디렉터리의 package.json 파일을 readFileSync를 사용해 바이너리 데이터로 읽은 다음, Buffer의 toString 메서드를 사용해 화면에 출력한다.