오늘은 비동기 챕터를 본격적으로 시작하며, 비동기 호출의 개념과 작동원리를 배우고 Callback, Promise, async/await 세가지 방법을 학습하고 실제 코드를 구현하는 스프린트를 진행하였다.
요청에 대한 결과가 동시에 일어나지 않는 것을 비동기적이라고 말하는데 비동기적으로 코드가 작동될 경우 어떤 로직이 끝날때까지 기다리지 않고 나머지 코드를 실행할 수 있다. 유튜브 사이트에서 동영상을 재생할 때 동영상이 로딩되기 전에도 댓글 창이나 재생목록이 렌더링 되는 것이 대표적인 예이다.
const printString = (string, callback) => { setTimeout( () => { console.log(string) callback() }, Math.floor(Math.random() * 100) + 1 ) } const printAll = () => { printString("A", () => { printString("B", () => { printString("C", () => {}) }) }) } printAll()
랜덤한 시간이 지나고 문자열을 출력하는 prinString 함수를 원하는 순서대로 출력되게 하기 위한 printAll이란 함수가 있다고 가정하면 위와 같은 형태로 prinString 내에 callback 함수를 설정해주면 된다. 그러나 순차적으로 실행해야 할 함수가 많은 경우 callback을 중첩해서 작성해야해서 (흔히 말하는 callback hell) 가독성이 떨어지는 형태로 코드를 작성하게 된다. 그래서 보통 Promise나 async/await을 사용한다.
const printString = (string) => { return new Promise((resolve, reject) => { setTimeout( () => { console.log(string) resolve() }, Math.floor(Math.random() * 100) + 1 ) }) } const printAll = () => { printString("A") .then(() => { return printString("B") }) .then(() => { return printString("C") }) } printAll()
prinString을 Promise의 새로운 인스턴스로 만들어주면 함수가 실행된 이후에 callback 함수가 실행되게 하는 방법 대신 .then을 사용하여 callback 함수와 동일하게 순차적으로 함수를 실행할 수 있다.
위 예에서는 resolve에 별도의 인자를 전달하지 않았지만 Promise 인스턴스가 실행된 후 .then을 사용하면 resolve('parameter')의 parameter를 받아올 수 있으며, .then을 이어서 사용할 경우 이전 .then에서 리턴된 값을 parameter로 불러올 수 있다.
또한 에러가 발생했을 때 reject가 실행되도록 설정해주면 .then을 건너뛰고 .catch가 실행되도록 할 수 있으며 인자가 전달되는 방식은 resolve와 동일하다.
const printString = (string) => { return new Promise((resolve, reject) => { setTimeout( () => { console.log(string) resolve() }, Math.floor(Math.random() * 100) + 1 ) }) } const printAll = async () => { await printString("A") await printString("B") await printString("C") } printAll()
async/await는 최근에 추가된 기능으로 Promise를 가독성있는 코드로 작성하기 위해 고안된 기능이다. 기존에는 .then을 사용하여 return 이후 다시 .then을 사용하는 방식으로 callback 기능이 구현되었다면 async 함수를 생성하여 .then 대신에 await을 써준 후 함수를 작성하면 동일하게 작동된다. 넘겨받은 인자를 불러오고 싶을때는 별도의 변수에 저장하여 사용하면 된다. (ex) let data = await print('a'))
다른 새로운 개념들과 마찬가지로 개념과 작동원리는 이해가 갔는데 실제로 코드를 작성하는 방법은 스프린트를 진행하면서 확실하게 이해할 수 있었다. parameter를 전달받는 방법과 resolve와 reject의 사용법을 익히면서 왜 비동기 함수를 사용하는지에 대해 이해할 수 있었다.