SEB[JS/Node :비동기]

Jogi's 코딩 일기장·2021년 7월 28일
0

이번 유닛에서는 비동기라는 것에 대해서 배웠다. 학교를 다닐 적에 동기화시킨다, 비동기화다 이런 말은 들어봤지만 제대로 들여다 본 것은 이번이 처음이라 이해하는데는 조금 어려움이 있었던 것 같다. 다시 배운 것들을 토대로 개념 정리와 느낀 점을 풀어보겠다.

우선 알고가야 하는 개념이나 정보가 있다.

  • blocking : 하나의 작업이 끝날 때까지 이어지는 작업을 막는 것.

  • node.jsnon-blocking하고 비동기적(asynchronous)으로 작동하는 런타임이다.

  • javascript의 비동기적 실행은 웹 개발에서 유용하다.

    • 백 그라운드 실행, 로딩 창의 작업
    • 인터넷에서 서버로 요청을 보내고, 응답을 기다리는 작업
    • 큰 용량의 파일을 로딩하는 작업
  • 비동기 흐름은 callback, Promise, async/await 중에서 하나의 문법을 이용해 구현 가능하다.

비동기(asynchronous)

비동기 호출

  • blocking(동기) : 요청에 대한 결과가 동시에 일어난다.

  • nonblocking(비동기) : 요청대 대한 결과가 동시에 일어나지 않는다.

  • 비동기 함수 전달 패턴

    • callback 패턴
      let req = 'choco';
      orderAsync(req, function(response) {
      	eat(response)                   // orderAsync 안의 function 부분
      });
    • 이벤트 등록 패턴
      let req = 'choco';
      orderAsync(req).onready = function(response) {
      	eat(response)                   // function 부분
      });
  • 비동기의 주요사례

    • DOM의 element 핸들러(I/O 입력(click, keydown 등), 페이지 로딩(DOMContentLoaded 등))
    • 타이머 (타이머 API(setTimeout 등), 애니메이션 API(requestAnimationFrame 등))
    • 서버에 자원 요청 및 응답(fetch API, AJAX(XHR))

Callback

  • 비동기라고 하면 예상할 수 없다와 같은 의미이다.

  • 순서를 제어하고 싶을 때는 callback을 이용한다. 비동기를 핸들링할 수 있는 방법 중의 하나이다.

  • callback이 너무 많을 경우에는 callback hell이라 부르는데 이를 해결하기 위해서는 Promise를 이용한다.

Promise and async/await

Promise

  • 일종의 클래스 같은 것이다. Promise를 사용할 때는 new 키워드를 통해서 사용한다.

    new Promise((resolve, reject) => {func});
  • 여기에서 resolve()는 task가 성공했을 때 다음 액션을 취하며, reject()는 task를 중지하고 에러를 핸들링한다.

  • 에러가 없을 경우 .then()으로 다음 task를 수행하며, 에러가 있으면 .catch()를 통해 실패 task를 수행한다. 마지막에 .catch()를 하는데 어디에서든 에러가 나면 마지막에 있는 catch()가 실행된다.

  • Promise의 세가지 상태

    • 대기(pending) : 비동기 처리의 결과를 기다리는 상태
    • 이행(fulfilled) : 비동기 처리가 정상적으로 끝났고 결과값을 가지고 있는 상태
    • 거부(rejected) : 비동기 처리가 비정상적으로 끝났음

async/await

  • await 키워드를 사용하기 위해서는 함수 앞에 async라는 키워드를 붙여줘야 한다.
    async function_name () {
    	await a             // a는 항상 Promise객체여야 한다. await은 Promise객체에 쓸 수 있다.
    }
    let func = async () => {
    	await b
    }

Promise hell이 발생하면 Promise Chain을 이용하며, 이보다 async/await을 쓰면 더 깔끔하게 코드를 볼 수 있다.

타이머 API

  • setTimeout(callback, milli) : 일정 시간(milli ms만큼) 후에 함수를 실행한다. 임의의 타이머 id를 리턴한다.

  • setInterval(callback, milli) : 일정 시간의 간격을 가지고 함수를 반복적으로 실행한다. 임의의 타이머 id를 리턴한다.

  • clearTimeout(timerId), clearInterval(timerId) : 타이머를 종료시킨다. 리턴은 없다.

Node.js 모듈인 fs

  • fs.readfile(path[, option], callback)
    • 비동기적으로 파일 내용 전체를 읽는다.
    • path : string | Buffer | URL | integer : 일반적으로 string
    • option : Object | string : 옵션은 넣을 수도 있고 생략할 수도 있다.
    • callback : Function
      • 콜백함수를 전달한다. 파일을 읽고 난 후에 비동기적으로 실행되는 함수다.
      • 콜백함수에는 두 가지 파라미터가 존재한다. 에러가 발생하지 않으면 err파라미터는 null이고, data 파라미터에 문자열이나 buffer라는 객체가 전달된다. data는 곧 파일의 내용이다.

fetch를 이용한 네트워크 요청

  • 비동기 요청의 가장 대표적인 사례는 네트워크 요청이다. 요청의 형태는 다양하지만 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 객체 앞에서만 사용할 수 있다는 것을 알 수 있었다. 이번 실습은 처음 접하고 낯선 개념이었는데 개념을 바로 익히고 실습을 바로하니 그래도 이해를 할 수는 있었다. 그래도 시간이 지나면 또 까먹을 수도 있을 것이기 때문에 복습은 중요할 것이다. 복습 많이하자.

Reference

  • 코드스테이츠 강의자료
profile
프로그래머로서의 한걸음

0개의 댓글