TIL - JavaScript의 동기와 비동기 :: Pre-Onboarding

UlongChaS2·2021년 8월 14일
2

Wanted Pre Onboarding

목록 보기
5/6
post-thumbnail

동기와 비동기! JavaScript를 하다보면 이건 비동기고 이건 동기고 이런 말은 무수히 듣는다. 그 뒤에 콜백함수, promise, async, await 이런 것들이 따라온다. 초보자에게는 너무 이해안되면서 무섭기도한 개념들,,,
드디어 오늘 예리멘토님❣️과 함께 부숴보려고한다👊 (feat. 드림코딩by엘리님)

🚶‍♀️🏃‍♀️동기와 비동기

🚶‍♀️동기

차례대로 코드가 진행되는 것

  • 장점 : 차례대로 진행되는 것

  • 단점 : 동작이 많은 함수가 있을 때 그 함수가 다 끝나지 않고서는 진행되지 않는다. (Task가 블로킹 된다고 함)
    ex. 서버로부터 받는 데이터가 무거워 늦게 받아지는 경우 그 다음 동작을 하지 못해 흰 화면만 띄워지게 된다.

🏃‍♀️비동기

차례대로 코드가 실행되지 않고도 다음으로 진행되는 것

  • 장점 : 블로킹이 생기지 않는다.

  • 단점 : 실행 순서가 보장 되지 않는다.

비동기가 필요한 이유

자바스크립트 엔진(브라우저) Single Thread이기 때문에 동기 문제로 Blocking(작업 중단)이 생기면서 처리하는 속도가 매우 느리게 될 것이다.

  • Single Thread : 한 번의 하나의 Task를 진행하는 것

ex. 응답을 기다리고 진행하는게 아닌 응답을 요청하고 다른 것이 실행되면서 응답을 받으면 처리하는 것
이게 동기라면 와이파이가 정말 느려질 것

동기 / 비동기 순서

setTimeout(function() {
    console.log('1');
}, 0); 

console.log('2');

for (let i = 0; i < 3; ++i) {
    loop();
}

setTimeout(function() {
    console.log('3');
}, 0); 

console.log('4');

function loop() {
    console.log('5');
}

동기인 2
함수도 동기로 작동하여 5, 5, 5
다시 동기인 4
비동기인 1, 3

여기에서 아무리 비동기가 0초 뒤에 작동한다 하더라도 브라우저에 한번 맡기고 동기가 실행되고 다시 비동기처리를 해주기 때문에 순서가 저렇게 된다.

AJAX

페이지 드래그하면 url 바꾸고 전체적으로 리로드
비동기방식 생기면서 필요한 데이터만 불러와 필요한 부분만 바꾼다.

브러우저가 서버에게 비동기방식을 데이터를 요청하고 응답한 데이터를 수신하여 일부를 동적으로 갱신 (fetch, await, aync 등)

콜백함수

함수의 매개변수가 함수 형태일 때 콜백함수라고 말한다.

(이 콜백함수를 매개변수를 받는 함수는 HOF(고차함수)라고 한다.)

주의할점이 콜백함수라고해서 항상 비동기로 작동하는게 아닌 개발자가 용도에 따라 동기인지, 비동기인지 지정해줘야한다.

  • synchronous callback : 동기 콜백함수
    즉각적으로 실행 되는 콜백함수

  • asynchronous callback : 비동기 콜백함수
    언제 실행될지 모르는 콜백함수

계속 인자를 함수형태로 넘겨서 쓰는 단점을 콜백 지옥이라한다.

콜백 지옥

인자를 계속해서 콜백함수를 부르는 것

콜백 지옥의 문제점

  • 가독성이 너무 안좋다.
  • 비즈니스 로직을 한눈에 알아보기도 너무 어렵다.
  • error가 발생했을 때와 디버깅을 할 때 문제 분석이 어렵다.
  • 위의 이유로 유지보수가 어렵다.

Promise

자바스크립트 내장 클래스로 비동기를 간편하게 처리할 수 있도록 도와주는 객체 (ES6)

resolve, reject

  • resolve : 성공했을 때
  • reject : 실패했을 때

resolve

let promise = new Promise(function(resolve, reject) {
	// 여기 비동기 로직을 작성! 
  
	// 완료 하면 -> resolve 호출
  // 비동기 동작 실패 하면 -> reject 호출
});

promise.then(function() { // 이 안의 인자는 원하는 만큼 받아도 된다.
	// 이 함수가 바로 위의 resolve 입니다.
	// 위의 비동기 로직이 성공하면 호출 됩니다!
});

자바스크립트에서 정의가 되어있는거라 따로 넘겨주지 않아도 딱히 error가 되지 않음
그리고 promise.then의 인자로 들어있는 함수가 resolve함수인 것은 이미 지정되어 있는 것이다.

reject

let promise = new Promise(function(resolve, reject) {

});

// then 인자 둘 다 cb 함수
// 첫 번째는 성공했을 때 실행할 resolve 함수 정의
// 두 번째는 실패했을 때 실행할 reject 함수 정의
promise.then(function() {}, function() {});

실패한 후에 메세지를 띄우고 싶을 때, 보통 error라는 클래스 객체를 만들어서 이용한다.

주의할 점

함수를 조건 넣어주지 않는 이상 많은 함수를 나열해놔도 reject든 resolve인지 상관없이 하나의 함수만 실행되고 끝난다.

자바스크립트는 하나하나씩 코드를 읽어나가서 동기코드 부터 한줄 씩 읽고 그 다음 비동기 코드를 읽는다.

인스턴스화 하자마자 실행되므로 비동기 요소들이 없고 안에 동기 요소만 있다고하면 동기 요소만 찍힘

chaining

순차적으로 각각의 작업이 이전 단계 비동기 작업이 성공하고 나서 그 결과값을 이용하여 다음 비동기 작업을 실행해야 하는 경우

state

promise는 객체의 상태를 가지고 있음.

  • Pending(대기): 비동기 처리 로직이 아직 완료되지 않은 상태
  • Fulfilled(이행): 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
  • Rejected(실패): 비동기 처리가 실패하거나 오류가 발생한 상태

💫 에러 처리

reject, catch

보통 에러 처리에는 reject, catch가 있는데, 두 번째 인자로 써야하는 reject를 잘 쓰지 않고 catch를 사용한다.

catch는 promise를 return하다보니 catch에서 멈추지않고 다음 동기 부분도 실행하게 된다.

'Error caught'로 문자열을 다음 .then의 인자로 넘기고 resolve였을 때
마지막에으로 이어지는 체이닝이 없어서 실행하지 않고 끝남

promise.finally, promise.all

promise.finally : resolve이든 reject이든 상관없이 실행되는 것
promise.all : 응답 값이 배열로 한 번에 옴

그치만 IE는 제공 되지 않기 때문에 폴리필로 하거나 바벨을 필수로 설치하고 사용해야한다.

async & await

ES8에 나온 문법으로 그 전까지는 promise로 썼었다.

async 함수는 promise를 반환함으로 promise도 잘 알아야한다.

즉시 실행 함수 (IIFE)

스코프를 막고 블락을 한정적이게 하기 위함


자바스크립트를 더욱 알아서 노드할 기회가 있으면 반드시 잡는게 중요하다.
- 멘토 예리님
이 말씀은 내 바운더리를 그냥 넓히라는 말이 아닌 자바스크립트를 근본적이게 알아야 JS로 이루어진 라이브러리, 프레임워크 등을 다루는 러닝커브가 높아진다라는 말씀이신 것 같다.
이론은 정말 부족하다고 미흡하다 생각하지만 그런 만큼 더욱 열심히, 복습하며 공부해야겠다!


0개의 댓글