비동기 프로그래밍이란 특정 코드의 처리가 다 끝나기 전에 아래로 계속 내려가면서 다음 코드를 진행하는 것을 말한다. nodejs에서 비동기 프로그래밍은 상당히 중요한 개념으로 코드의 효율성과 성능을 최대한으로 활용할 수 있다.
비동기 프로그래밍을 설명할 때 예시로 요리를 많이 든다. 예를 들어 다음과 같은 제육볶음 레시피가 있다.
이 레시피를 초보 요리사가 따라해본다고 치면 과정은 이럴 것이다.
요리의 과정에서 시간을 단축하는 방법은 기다리는 과정을 최소화하는 것이다. 3번과 4번을 기다리는 데에는 꽤나 많은 시간이 필요하니 고수 요리사는 이를 보완하여 다음과 같은 과정으로 요리할 것이다.
기다리는 과정과 절차의 갯수가 확실히 줄어들어 더 효율적인 과정으로 요리했다고 볼 수 있다.
동기 프로그래밍과 비동기 프로그래밍의 차이는 바로 이것이다. 초보 요리사의 요리 과정을 동기 프로그래밍이라고 하고, 고수 요리사의 요리 과정을 비동기 프로그래밍이라고 하면 이해하기 쉬울 것이다. 초보 요리사의 요리 과정에는 기다리는 과정에서 다른걸 하지 않아 시간이 많이 소요되었지만, 고수 요리사의 요리 과정에는 기다리며 다른 일을 했기 때문에 더 빠르게 처리할 수 있었다. 이와 같이 비동기 프로그래밍은 한 코드가 실행되는 동안 처리가 끝날 때까지 기다리지 않고 다음 코드를 처리하는 것을 말한다.
비동기 프로그래밍을 응용하기 위해서는 콜백(callback) 함수에 대해서 이해할 필요가 있다. 간단히 말해 함수의 호출이 끝나고 실행될 함수를 따로 받는 함수를 뜻한다. 말이 조금 복잡한데, 예시를 들자면
어떤 사용자가 웹페이지를 접속한다고 하자. 이 웹페이지는 서버에 있는 특정 파일을 불러와서 그 내용을 출력하는 웹페이지이다. 접속을 했을 때 서버에서는 파일의 내용을 출력하기 위해 파일을 불러올 것이다. 그런데 어떠한 이유로 인해 파일을 불러오는 데 시간이 조금 걸릴 수 있다. 그러면 사용자는 그 시간 동안 웹페이지에서 아무런 정보도 찾을 수 없고, 이로 인해 그냥 아무것도 없는 웹사이트라고 생각하고 페이지를 끌 수도 있다. 이를 방지하기 위해 파일을 불러오는 중에 'Loading..'과 같은 문구를 출력해 놓으면 좋다. 이를 코드로 작성해보면
import fs from "fs"
fs.open("./memo.txt", 'r', (err, fd) => {
if(err){
console.log(err)
return
}
fs.read(fd, (err, bytes, bf) => {
if(err){
console.log(err)
return
}
console.log(bf.toString())
})
})
console.log("Loading..")
위의 코드는 언뜻 보면 memo.txt
파일을 불러와 결과를 출력한 후 Loading..
이라는 메시지를 출력할 것처럼 보일 수 있지만, 그렇지 않다. 실행해 보면 Loading..
이후 파일의 내용이 출력되는 것을 확인할 수 있는데, 이는 open()
함수가 호출된 후 처리가 끝나기 전에 밑에 있는 코드가 실행되었다는 것을 뜻한다. 그리고 이 코드에서 사용된 연산자 중 조금 특이한 =>
이 보이는데, 이것은 함수를 작성하는 연산자라고 보면 될 듯 한다. 그러니까 open()
함수를 해석해보면 memo.txt 파일을 읽기 전용으로 열고 에러가 나면 에러를 출력하고 프로그램 종료, 에러가 없으면 read()함수를 호출해 파일의 내용 출력이라고 볼 수 있다. 이 과정을 거치는 동안 생기는 대기시간에서 Loading..
이라는 문구를 출력하는 것이다.