자바스크립트와 프로미스 share
자바스크립트를 처음 접했을 때 프로미스(Promise)가 어려웠다. 일반적으로 컴퓨터 프로그램은 여러 개의 로직(작업)을 순차적으로 수행한다. 시간이 오래 걸리는 로직이 끼어 있으면 다음 로직은 앞의 로직이 끝나기를 기다려야 한다.
자바스크립트도 앞서 언급한 것 처럼 순차적으로 실행되지만, 시간이 오래 걸리는 작업은(e.g. 파일 IO, 네트워크 IO), 작업이 끝나면 실행할 콜백을 심어 놓고, 그냥 다음 로직으로 진행한다. 콜백에 콜백을 등록하고, 또 그 콜백에 콜백을 등록하는 “콜백 지옥”을 경험하게 된다. 콜백 지옥을 완화하기 위해 자바스크립트가 제시한 방안이 프로미스다.
난 프로미스를 임시로 고용한 작업자라고 이해했다. ‘난 바빠서 다음 일 처리하러 가야 하는데요. 철수님, “Foo” 작업을 대신 좀 봐 주세요. 대략 5초 정도 걸릴거에요. “Foo” 작업이 끝나면 “성공콜백”을 실행해주세요.’
이하 코드들은 크롬 콘솔(Cmd+Shift+c)에 붙여 넣으면 동작을 확인해 볼 수 있다.
1. Promise
var 철수 = new Promise(function (성공콜백, 실패콜백) {
console.log('철수 작업자가 할당되었습니다.');
setTimeout(function () {
console.log('5초가 필요한 "Foo" 작업을 시뮬레이션합니다.');
성공콜백('Foo');
}, 5000);
});
철수.then(function (작업이름) {
console.log('"' + 작업이름 + '" 작업이 성공하면 철수에게 실행해 달라고 부탁한 로직입니다. 이 메시지가 표시된다면 철수가 로직을 실행한 것입니다.');
});
철수
는 Promise
클래스의 인스턴스다. Promise
클래스는 then()
API를 가지고 있고, 함수를 인자로 받는다. 인자로 받은 함수는 다시 성공 또는 실패했을 때 실행할 콜백을 인자로 받는다.
자바스크립트는 개발자가 제어할 수 없는 클라이언트에서 작동하고, 클라이언트 측의 인코딩때문에 어떤 문제가 발생할 지 전혀 예측할 수 없다. 실무에서 한글 코딩은 비추한다.
2. ES6
똑같은 코드를 ES6로 쓰면,
let 철수 = new Promise((성공콜백, 실패콜백) => {
console.log('철수 작업자가 할당되었습니다.');
setTimeout(() => {
console.log('5초가 필요한 "Foo" 작업을 시뮬레이션합니다.');
성공콜백('Foo');
}, 5000);
});
철수.then(
작업이름 => console.log(`"${작업이름}" 작업이 성공하면 철수에게 실행해 달라고 부탁한 로직입니다. 이 메시지가 표시된다면 철수가 로직을 실행한 것입니다.`)
);
오늘도 Coffee 스크립트를 많이 사용하는 프레임워크 모임에 다녀왔는데, 이제 Coffee를 쓸 이유가 없다. ES6가 Coffee의 문법을 거의 대부분 채택하고 있기 때문이다. 그림에서 보다시피 최신 브라우저에서는 ES6 -> ES5 컴파일하지 않고도 최신 문법이 작동한다(내 최신 브라우저에서 작동한다고, 다른 이의 브라우저에서 작동한다고 보장할 수 없으므로 아직은 컴파일해야 한다). Prototype
등 익숙치 않은 개념은 이제 class
, constructor
, static
등 다른 언어에서 항상 쓰던 문법으로 교체되었다.
3. 결론
자고 일어나면 새로운 기술이 나오는 시대에서 풀 스택 웹 개발자로 살아가기란 힘들다. 나처럼 서버 사이드에서 시작한 사람이 자바스크립트를 익힐 때 가장 먼저 만난 벽은 이벤트 프로그래밍이었고(블로킹 vs 논-블로킹 IO, Sync vs Async), 그 중에서도 프로미스였다. 이 포스트는 나만의 프로미스 이해 방식을 정리한 것이다.
풀스택 개발자를 지향하는 후배들이 조언을 요청하면 요즘은 항상 이렇게 답해준다. 2016년에 배워야 할 프런트 엔드 기술은 1) ES6 2) 본문에 언급은 없었지만, 제이쿼리에서 Vue.js등 양방향 데이터 바인딩을 지원하는 라이브러리로 마이그레이션하는 것, 두 가지라고. 여유가 된다면 3) 빌드 시스템과 4) 태스크 러너도 배우면 좋다.
다행히 내가 주력으로 하는 라라벨 웹 프레임워크는 Webpack 빌드 시스템과, Gulp 태스크 러너를 기본으로 사용하고 있어 두 개의 짐은 덜었다.