-
예측 가능한 콜백, Promisejavascript 2020. 1. 30. 19:45
자바스크립트 비동기 처리 면에서 Promise는, 콜백을 주체적으로 사용할 수 있게 한다.Promise는 자바스크립트 비동기 처리에 사용되는 객체이다.
주로 서버에 요청한 데이터를 받은 후, 화면에 표시할 수 있도록 핸들링할 때 사용한다.
ㄴ 데이터를 다 받기도 전에 화면에 표시하려 하면 빈화면 또는 오류가 발생한다.기존의 비동기 처리에는 콜백함수가 주로 쓰였는데 여러 단점들이 있었고, 이를 개선하는 Promise가 라이브러리로 생겨난 후 ES6에서 언어적 차원으로 지원하여 사용되고있다.
Promise를 정리하기 전에, 어떤 면에서 개선되었는지 살펴보았다.
콜백함수 단독 사용에 비하여 Promise는
콜백함수의 중첩으로 인한 복잡성을 해결해준다.
콜백함수의 중첩은 비동기 함수의 처리 결과를 가지고 다른 비동기 함수를 호출할 때 생겨난다.
콜백이 실행되면 다음 콜백을 실행하고, 그 다음 콜백을 실행하고...
아래와 같이 콜백 안에 콜백을 계속 무는 상황을 이야기하며 일명 'Callback Hell'이라 하기도 한다.
$.get('url', function (response) { parseValue(response, function (id) { auth(id, function (result) { display(result, function (text) { console.log(text); }); }); }); });
Promise 객체를 생성하고 then메서드를 활용하면 이런 콜백지옥의 상황을 눈에띄게 정리해줄 수 있다.
then메서드를 간단하게만 미리 남겨두자면,
promise 내부에서 실행이 완료(성공)되면 then 뒤의 함수를 실행한다.
then메서드는 promise를 반환하여, then뒤에 then을 계속 이어가며 다음 실행할 것들을 비교적 예쁘게 줄지어 놓을 수 있다.const promise = new Promise((resolve, reject) => { setTimeout(() => { if(true) { resolve('성공'); } else { reject('실패'); } }, 1000); }); promise .then(function one(message) { // resolve가 실행되면 console.log(message); return 3; }).then(function two(number) { // function one이 실행되면 console.log(number); });
에러/예외케이스를 잘 핸들링해준다.
try블록 내 비동기처리 함수에서 에러가 발생하면, catch블록에서 캐치되지 않는다.
try { setTimeout(() => { throw new Error('Error!'); }, 1000); } catch (e) { console.log('에러를 캐치하지 못한다..'); console.log(e); }
setTimeout함수는 비동기 함수이므로 콜백 함수 실행될때까지 기다리지 않고 즉시 종료되어 콜스택에서 제거된다.
이후 timer함수의 tick이벤트가 발생하면 태스크 큐로 이동한 후, 이벤트루프를 통해 콜스택이 비어졌을 때 이동되어 실행된다.
setTimeout함수의 콜백 함수 내에서 발생된 에러는 호출자 방향으로 전파되어야 한다.
호출자는 콜스택에서 setTimeout 함수의 아래에 남아있기 마련인데, 다 비워진 채로 콜백함수가 실행되었기 때문에 호출자는 사실상 존재하지 않는다.따라서 setTimout함수의 콜백 함수 내에서 발생된 에러는 catch블록에서 캐치되지 않아 프로세스는 그냥 종료된다.
Promise 객체를 생성하고 catch메서드를 활용하면 이런 길 잃은 에러를 모아서 처리해줄 수 있다.
const promise = new Promise((resolve, reject) => { setTimeout(() => { if(false) { resolve('성공'); } else { reject('실패'); } }, 1000); }); promise .then(function one(message) { // resolve가 실행되면 console.log(message); return 3; }).catch((error) => { // reject가 실행되거나, then에서 에러 발생 시 console.error(error); });
비동기의 흐름을 주체적으로 컨트롤 할 수 있도록 객체를 준다.
콜백함수만 사용했을 때는, 콜백을 넘겨줄 때까지 수동적으로 마냥 기다리는 입장이었다.
promise 객체는 말그대로 객체이기 때문에 변수에 담고, 리턴하며 주체적으로 핸들링 할 수 있게 되며인자로도 넘길 수 있어 확장성이 있다.
// 객체이기 때문에 prototype으로 확장이 가능 Promise.prototype.map = function(fn) { };
'javascript' 카테고리의 다른 글
Learning JavaScript 후기 1 (0) 2020.02.02 Promise의 프로토타입 then과 catch (0) 2020.01.31 Promise의 생김새와 3가지 상태 (0) 2020.01.31 자바스크립트에서 call, apply, bind (0) 2020.01.31 변수 선언 var, let, const의 차이 (0) 2020.01.29