JS_비동기

비동기 호출

자바스크립트의 비동기 호출이란 특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성을 의미


비동기의 주요 사례

DOM Element의 이벤트 핸들러

  • 마우스, 키보드 입력 (click, keydown 등)

  • 페이지 로딩 (DOMContentLoaded 등)

타이머

  • 타이머 API (setTimeout 등)

  • 애니메이션 API (requestAnimationFrame)

서버에 자원 요청 및 응답

  • fetch API

  • AJAX (XHR)


타이머 API

setTimeout(callback, millisecond)

일정 시간 후에 함수를 실행

  • arguments: 실행할 callback 함수, callback 함수 실행 전 기다려야 할 시간 (밀리초)
  • return value: 임의의 타이머 ID
setTimeout(function() {
  console.log('1초 후 실행');
}, 1000);
// 123

setInterval(callback, millisecond)

일정 시간의 간격을 가지고 함수를 반복적으로 실행

  • arguments: 실행할 callback 함수, 반복적으로 함수를 실행시키기 위한 시간 간격 (밀리초)
  • return value: 임의의 타이머 ID
setInterval(function() {
  console.log('1초마다 실행');
}, 1000);
// 345

clearTimeout(timerId)

setTimeout 타이머를 종료

  • arguments: 타이머 ID
  • return value: 없음
const timer = setTimeout(function() {
  console.log('3초 후 실행');
}, 3000);
clearTimeout(timer);
// setTimeout 타이머를 취소함

clearInterval(timerId)

반복 실행 중인 타이머를 종료

  • arguments: 타이머 ID
  • return value: 없음
const intervalTimer = setInterval(function() {
  console.log('1초마다 실행');
}, 1000);
clearInterval(timer);
// 더 이상 반복 실행되지 않음

비동기를 제어하는 방법

1. callback

비동기를 제어하는 기본적인 방법은 callback 함수를 사용하여 제어한다.

비동기로 처리할게 많아지면 callback chain(Hell)에 빠진다.

callback chain의 단점

  • 가독성이 안좋음
  • 비즈니스 로직을 이해하기 힘듦
  • 디버깅 할 때 굉장히 복잡해지고 어려움
  • 유지/보수가 안좋음

2. Promise

Promise는 JS에서 제공하는 비동기 코드를 간편하게 처리할 수 있도록 도와주는 object 이다.

Promise는 어떤 기능을 실행하고 나서 정상적으로 동작하면 성공의 메세지와 함께 처리된 결과값을 전달해줌
그러나 기능을 수행하다 예상치 못한 문제가 발생하면 error를 전달해 준다.

Promise State: pending (보류) → fulfilled (이행) or rejected (거부)


Server

const promise = new Promise((resolve, reject) => {
  // 시간이 오래 걸리는 무거운 처리 (network, read files ..)
  console.log(`doing something...`);
  setTimeout(() => {
    resolve(`success`); // 성공 하면
    // reject(new Error(`no network`)); // 실패 하면
  }, 2000);
});
  • resolve : 처리 성공할 시 인자를 넘겨줌
  • reject : 에러(실패)가 날시 인자를 넘겨줌

Client

promise
  .then((value) => { // resolve 인자를 받음
    console.log(value);
  })
  .catch(error => { // reject 인자를 받음
    console.log(error);
  })
  .finally(() => { // 성공하든 실패하든 마지막에 실행됨
    console.log(`finally`);
  })

Promise chaining

then으로 값을 바로 전달 할 수 도 있고, 리턴으로 Promise를 전달할 수 있다.


Promise.all, Promise.race

Promise.all([함수, 함수]) : Promise 비동기 처리를 배열 형태로 간단하게 묶어줌

Promise.race([함수, 함수]) : 비동기 처리중 먼저 리턴하는 것만 출력


3. aync, await

Promise chaining도 계속 중첩되면 callback chain처럼 코드의 가독성이 떨어짐

asyncawaitPromise를 간결/간편하고 동기적으로 실행되는것 처럼 보이게 만들어주는 API

awaitasync 함수 내부에서만 사용 가능

try, catch로 에러를 처리함


function delay(ms) {
  return new Promise (resolve => setTimeout(resolve, ms));
}

async function getApple() {
  await delay(1000);
  // throw new Error(`error: apple`); // error 발생
  return `🍎`;
}
async function getBanana() {
  await delay(1000);
  // throw new Error(`error: banana`);
  return `🍌`;
}

async function pickFruits() {
  let apple = null;
  try {
    apple = await getApple();
  } catch(error) {
    console.log(error);
  }
  let banana = null;
  try {
    banana = await getBanana();
  } catch(error) {
    console.log(error);
  }
  return `${apple} + ${banana}`;
}
pickFruits().then(result => console.log(result));

Node.js의 fs module

Node.js 모듈 사용법

  1. 내장 모듈 사용법
const fs = require('fs')
  1. 써드파티 모듈 사용법
npm install [모듈명]  // CLI
const 모듈변수 = require('모듈명'); // 모듈 설치후 불러옴

fs.readFile 사용법

fs.readFile(path[, options], callback) 기본 형태

fs.readFile('test.txt', 'utf8', (err, data) => {
  if (err) {
    throw err; // 에러를 던짐
  }
  console.log(data);
});

fetch API

비동기 요청인 네트워크 요청 중 URL로 요청하는 경우 사용하는 API

웹사이트에서는 해당 정보만 업데이트하기 위해 자바스크립트 그 중에서도 fetch API를 사용해 해당 정보를 원격 URL로부터 불러옴

fetch API특정 URL로부터 정보를 받아오는 역할을 해주며 이 과정이 비동기로 이루어지기 때문에 경우에 따라 다소 시간이 걸리는 작업을 요구할 경우 blocking이 발생하면 안되므로 특정 DOM에 정보가 표시될때까지 로딩창을 대신 띄우는 경우도 많이 있다.

fetch API 사용법

const url = 'URL 주소';

fetch(url)
  .then(response => response.json()) // 요청 받은 것을 json으로 변환시켜 응답함
  .then(json => console.log(json))
  .catch(error => console.log(error));

fetch APIPromise의 형식으로 이루어짐
(chaining, Promise.all, async/await 사용 가능)

좋은 웹페이지 즐겨찾기