JavaScript에서 프로미스 소개
비동기 처리를 위해 콜백 모델을 사용하면 콜백 헬(callback hell)에 쉽게 빠질 수 있다는 것을 이미 알고 계실 것입니다. 그래서 JavaScript에는 프로미스(promise)라는 새로운 모델이 도입되었습니다. 이 모델을 함께 알아보도록 하겠습니다.
프로미스는 객체로서, 생성자에 매개변수로 전달되는 함수 내부에 비동기 코드를 작성합니다:
let promise = new Promise(function() {
// 비동기 코드
});
보시다시피, 프로미스 객체를 promise 변수에 저장했습니다. 코드의 다른 부분에서 이 변수에 then 메서드를 적용하여, 해당 프로미스 생성 시 작성된 비동기 코드가 완료되었을 때 실행되어야 할 코드를 담은 함수를 전달할 수 있습니다:
promise.then(function() {
// 비동기 코드 완료 시 실행됨
});
말로만 들으면 복잡하니, 예시를 통해 살펴보겠습니다. 다음과 같은 비동기 코드가 있다고 가정해 보죠:
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
여기서 비동기 처리의 주요 과제인, 타이머가 작동한 후 특정 코드를 실행하고 싶습니다. 이 코드를 타이머 내부에 직접 작성하고 싶지 않으며, result 변수에 작성한 결과가 어떻게든 이 코드에 전달되기를 원합니다. 이전 수업에서 콜백과 구독을 통해 이 문제를 해결했었죠. 이번에는 프로미스를 통해 어떻게 해결하는지 알아보겠습니다.
먼저 비동기 코드를 프로미스로 감싸야 합니다:
let promise = new Promise(function() {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
하지만 이것만으로는 충분하지 않습니다. 우리는 비동기 코드가 완료되었음을 명시적으로 표시해야 합니다. 이때 첫 번째 매개변수로 지정된(지정된다면) 함수에 자동으로 전달되는 특별한 완료 함수가 도움이 됩니다:
let promise = new Promise(function(resolve) { // 매개변수 지정
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
이 완료 함수를 사용하여 프로미스에게 비동기 코드가 완료되었음을 명시적으로 알릴 수 있습니다. 이를 위해 원하는 위치에서 이 함수를 호출해야 합니다:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(); // 프로미스 완료
}, 3000);
});
또한, 비동기 코드의 결과를 외부로 전달하려는 경우, 이 완료 함수의 매개변수로 결과를 전달할 수 있습니다:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(result); // 결과 전달
}, 3000);
});
물론 중간 변수를 제거할 수도 있습니다:
let promise = new Promise(function(resolve) {
setTimeout(function() {
resolve([1, 2, 3, 4, 5]);
}, 3000);
});
이제 코드의 다른 곳에서 프로미스의 then 메서드를 호출할 수 있습니다:
promise.then(function() {
// 프로미스 완료 시 실행됨
});
프로미스의 실행 결과는, 지정하기로 한다면 함수의 첫 번째 매개변수로 전달됩니다:
promise.then(function(result) {
console.log(result); // 결과 배열 출력
});
5초의 지연 후, 프로미스가 완료되고 어떤 텍스트를 결과로 반환하도록 프로미스를 만들어보세요. 그 텍스트를 화면에 출력하세요.