자바스크립트 비동기 처리

5o_hyun·2022년 2월 25일
0
post-thumbnail

동기 vs 비동기

동기 ( sync ) : 요청을 보낸 후 해당 요청의 응답을 받아야 다음 동작을 실행 ( 실행 순서 확실 ) 순차적
--------------------> 일반적으로 우리가 쓰는 코드는 동기적으로 실행
비동기 ( async ) : 요청을 보낸 후 응답과 관계없이 다음 동작을 실행 ( 실행 순서 불확실 )

자바스크립트의 비동기 처리

자바스크립트는 싱글스레드 언어이기 때문에 한번에 하나의 작업만 수행이 가능하다. ( Call stack 이 하나뿐이다. )
따라서 여러가지 이벤트를 처리할 때 동기식으로 처리하게 된다면 하나의 이벤트가 모두 처리될 때 까지 다른 업무를 수행하지 못하는 단점이 존재한다.
이를 해결하기위해 비동기 처리를 필요로 한다.
즉시 처리하지 못하는 이벤트들을 Web API라는 다른 선로에 올려놓는다.
Web API에서 각각 비동기 처리소로 이동하고, 비동기처리소에 도착한 순서대로 Task Queue 또는 Event Queue 에 순서대로 대기시킨다.
Call stack이 모두 비워졌을 때 Event Loop라는 장치가 순서대로 Call stack에 올려놓는다.
즉, 가장 빠른 것부터 처리되므로 Web API로 들어오는 순서는 중요하지 않고, 어떤 task가 먼저 처리되느냐가 중요하다. 따라서 명확한 실행순서가 존재하지 않는다.

console.log(1);
console.log(2);
setTimeout(() => {
  console.log(3);
});
console.log(4);

// 1 2 4 3

하지만 서버에 A라는 데이터를 요청하는 비동기 처리 후에 그 A 데이터를 이용해 B정보를 다시 요청해야하는 상황이라면 첫 번째 A라는 데이터 요청, 두 번째 A를 이용해 B 정보를 요청 이라는 흐름이 중요해진다. A가 없는 상황에서 B를 불러오지를 못하기 때문이다. 따라서 이러한 흐름을 처리하는 방식으로 콜백함수가 있다.

콜백함수

콜백함수 사용 전

const posts = [
  { title: 'Post One'},
  { title: 'Post Two'}
];

const getPosts= () => {
    setTimeout(() => {
    let output = '';
    posts.forEach((post) => {
      output += `<li>${post.title}</li>`;
    });
    document.body.innerHTML = output;
  }, 1000);
 };

const createPost = (post) => {
  setTimeout(() => {
    posts.push(post);
  }, 2000);
};

createPost({ title: 'Post Three'});
getPosts();

다음은 비동기처리 방식을 이해하지 못한 예문이다.
get과 create는 둘 다 setTimeOut이 있기 때문에 비동기 방식이다.
따라서 Web API로 경주를 하는데 get이 1초 create가 2초 걸리므로 get이 먼저 도착한다.
이벤트 큐 에는 get create 순으로 쌓이게 되며 이벤트루프를 통해 콜스택이 차례대로 쌓여 실행된다.
get -> create 순으로 실행된다. 3번째 post를 만드는 create가 동작하기전에 get이 실행되어 2개의 포스트만 보여지게 된다.

따라서 이러한 흐름을 제어하기 위해 콜백함수를 사용한다.

콜백함수 사용 후

const posts = [
  { title: 'Post One'},
  { title: 'Post Two'}
];

const getPosts= () => {
    setTimeout(() => {
    let output = '';
    posts.forEach((post) => {
      output += `<li>${post.title}</li>`;
    });
    document.body.innerHTML = output;
  }, 1000);
 };

const createPost = (post, callback) => {
  setTimeout(() => {
    posts.push(post);
    callback(post);
  }, 2000);
};

createPost({ title: 'Post Three'}, getPosts);

콜백함수를 사용하면 처음 의도했던대로 작성이 가능하다.
하지만 이러한 콜백함수들을 계속 사용하는것은 콜백함수안에 콜백함수가 있고 그 콜백함수안에 또다른 콜백함수가 있는식이다.
가독성이 떨어지고 디버깅이 상당히 힘들어지는 일명 콜백지옥이 발생한다.
이러한 콜백지옥을 벗어나기위해 Promise를 사용한다.

profile
학생 점심 좀 차려

0개의 댓글