이번 유닛에서는 비동기라는 것에 대해서 배웠다. 학교를 다닐 적에 동기화시킨다, 비동기화다 이런 말은 들어봤지만 제대로 들여다 본 것은 이번이 처음이라 이해하는데는 조금 어려움이 있었던 것 같다. 다시 배운 것들을 토대로 개념 정리와 느낀 점을 풀어보겠다.
우선 알고가야 하는 개념이나 정보가 있다.
blocking : 하나의 작업이 끝날 때까지 이어지는 작업을 막는 것.
node.js는 non-blocking하고 비동기적(asynchronous)으로 작동하는 런타임이다.
javascript의 비동기적 실행은 웹 개발에서 유용하다.
비동기 흐름은 callback, Promise, async/await 중에서 하나의 문법을 이용해 구현 가능하다.
blocking(동기) : 요청에 대한 결과가 동시에 일어난다.
nonblocking(비동기) : 요청대 대한 결과가 동시에 일어나지 않는다.
비동기 함수 전달 패턴
let req = 'choco'; orderAsync(req, function(response) { eat(response) // orderAsync 안의 function 부분 });
let req = 'choco'; orderAsync(req).onready = function(response) { eat(response) // function 부분 });
비동기의 주요사례
비동기라고 하면 예상할 수 없다와 같은 의미이다.
순서를 제어하고 싶을 때는 callback을 이용한다. 비동기를 핸들링할 수 있는 방법 중의 하나이다.
callback이 너무 많을 경우에는 callback hell이라 부르는데 이를 해결하기 위해서는 Promise를 이용한다.
일종의 클래스 같은 것이다. Promise를 사용할 때는 new 키워드를 통해서 사용한다.
new Promise((resolve, reject) => {func});
여기에서 resolve()는 task가 성공했을 때 다음 액션을 취하며, reject()는 task를 중지하고 에러를 핸들링한다.
에러가 없을 경우 .then()으로 다음 task를 수행하며, 에러가 있으면 .catch()를 통해 실패 task를 수행한다. 마지막에 .catch()를 하는데 어디에서든 에러가 나면 마지막에 있는 catch()가 실행된다.
Promise의 세가지 상태
await 키워드를 사용하기 위해서는 함수 앞에 async라는 키워드를 붙여줘야 한다.async function_name () { await a // a는 항상 Promise객체여야 한다. await은 Promise객체에 쓸 수 있다. } let func = async () => { await b }
Promise hell이 발생하면 Promise Chain을 이용하며, 이보다 async/await을 쓰면 더 깔끔하게 코드를 볼 수 있다.
setTimeout(callback, milli) : 일정 시간(milli ms만큼) 후에 함수를 실행한다. 임의의 타이머 id를 리턴한다.
setInterval(callback, milli) : 일정 시간의 간격을 가지고 함수를 반복적으로 실행한다. 임의의 타이머 id를 리턴한다.
clearTimeout(timerId), clearInterval(timerId) : 타이머를 종료시킨다. 리턴은 없다.
비동기 요청의 가장 대표적인 사례는 네트워크 요청이다. 요청의 형태는 다양하지만 URL로 요청하는 경우가 일반적이다.
URL로 요청이 가능하게 해주는 API가 fetch API이다.
fetch API는 특정 URL로부터 정보를 받아오는 역할을 한다. 이 과정이 비동기로 이루어지기 때문에 경우에 따라 다른 시간이 걸릴 수 있다. 이와 같이 시간이 소요되는 작업을 요구할 경우에는 blocking이 발생하는데, 정보가 표시될 때까지 로딩창을 대신 띄우기도 한다.
사용예시
let url = "https://velog.io/write?id=3f077043-56cf-4a7e-88a5-ccb0e88bbabd"; fetch(url) .then((response) => response.json()) // 자체적으로 json()메소드가 있어, 응답을 JSON형태로 변환시켜 전달한다. .then((json) => console.log(json)) . catch((err) => console.log(err));
실습은 위에서 배운 비동기 처리를 하기 위한 callback의 이용, Promise를 이용, async/await를 이용한 연습이었다. Promise에서는 기본 사용법과 체이닝, Promise.all, async/await을 이용해서 파일읽기와 네트워크 요청으로 받은 자료 가공에 대한 실습을 진행했다. 두 가지 실습 모두 비슷한 구조로 이루어졌기 때문에 전 실습만 할 수 있었다면 다음 실습은 쉽게 할 수 있었다. 체이닝하는 과정이 어려웠는데 then이 전에 실행한 Promise 객체의 리턴값을 받아 사용할 수 있다는 것을 깨닫고는 어렵지 않게 해결할 수 있었다. 또한 async/await에서도 await을 사용할 수 있는 것은 Promise 객체 앞에서만 사용할 수 있다는 것을 알 수 있었다. 이번 실습은 처음 접하고 낯선 개념이었는데 개념을 바로 익히고 실습을 바로하니 그래도 이해를 할 수는 있었다. 그래도 시간이 지나면 또 까먹을 수도 있을 것이기 때문에 복습은 중요할 것이다. 복습 많이하자.