45. 프로미스 - 기존 콜백 패턴의 단점

Sooo·2023년 9월 9일
0

요약

Promise

  • 전통적인 비동기 처리 방식인 콜백 패턴을 보완하고자 es6에서 추가된 새로운 비동기 처리 방식.
  • 비동기 처리 시점을 명확히 표현 가능

기존 콜백 패턴의 단점

  • 비동기 함수 안의 비동기코드가 완료되기 전에 비동기 함수가 먼저 종료됨. 따라서 비동기 코드의 결과를 리턴하거나 상위 스코프의 변수를 바꿀 수 없음.
    • 예시의 xhr.load 이벤트 핸들러 프로퍼티에 바인딩한 이벤트 핸들러는 아래의console.log보다 항상 늦게 실행된다.

      const get = url => {
      	const xhr = new XMLHttpRequest();
      	xhr.open('GET', url);
      	xhr.send();
      	
      	xhr.onload = () => {
      		if (xhr.status == 200) {
      			//1. 서버의 응답을 상위 스코프의 변수에 할당한다.
      			todos = JSON.parse(xhr.response);
      		}	else {
      			console.error(`${xhr.status} ${xhr.statusText}`);
      		}
      	}
      }
      // id가 1인 post를 취득
      get('https://jsonplaceholder.typicode.com/posts/1');
      console.log(todos); // 2. undefined
      
    • 만약 console.log(todos) 가 실행되기 전에 load 이벤트가 발생했더라도, 콜스택에 쌓인 실행컨택스트를 모두 실행한 후에야 이벤트 루프가 태스크 큐에 저장된 load 이벤트 핸들러를 콜스택으로 푸시하므로 이벤트 핸들러가 console.log 이전에 실행될 수는 없다.

    • 따라서 비동기 함수는 비동기 처리 결과를 외부에 반환할 수 없고, 상위 스코프의 변수에 할당할 수 없다.

    • 비동기 처리 결과에 대한 후속 처리를 수행하는 콜백 함수를 전달하는 게 일반적이다

      1. 콜백 헬

      비동기 처리 결과에 대한 후속 처리를 수행하는 콜백 함수가 결과를 가지고 다시 비동기 함수를 호출한다면 콜백 함수 안에서 다시 콜백 함수를 불러 복잡해진다 ⇒ 콜백 헬

      : 코드의 가독성이 떨어지며 실수하기 쉽다

      2. 에러 처리의 어려움

      에러는 호출자 방향(즉, 콜스택의 바로 아래 실행컨텍스트)으로 전파된다. 그런데 setTimeout에서 받아온 콜백함수의 호출자는 setTimeout이 아니다. setTimeout함수는 호출된 후 콜백함수의 실행을 기다리지 않고 즉시 종료되어 콜스택에서 제거되고, 콜백함수는 타이머 만료 후 태스크 큐에 등록되었다가 콜스택이 비었을 때 콜스택에 푸시된다. 따라서 에러가 발생했을 때 받아줄 호출자가 없다

0개의 댓글