https://www.codingame.com/playgrounds/347/javascript-promises-mastering-the-asynchronous
간단한 프로미스 퀴즈가 3개 있다.
다 맞은 기념으로 풀이를 정리해보고자 한다.
1번
function job() {
return new Promise(function(resolve, reject) {
reject();
});
}
let promise = job();
promise
.then(function() {
console.log('Success 1');
})
.then(function() {
console.log('Success 2');
})
.then(function() {
console.log('Success 3');
})
.catch(function() {
console.log('Error 1');
})
.then(function() {
console.log('Success 4');
});
출력결과를 예측해보자.
job
함수는 수행될 시 rejected
상태인 프로미스 를 반환한다.
rejected
상태는 promise의 체이닝 단계에서 catch
혹은 onReject (then의 두번째 파라미터로 주어지는 함수)
를 만날 때까지 이동한다.
따라서, catch 구문이 있는 곳까지 이동하게 되고 Error 1
을 출력한다.
여기서 catch 구문에 반환 값이 명시되어있지 않기 때문에 undefined
가 반환되었다고 인식하고 undefined
를 데이터로 갖는 fulfilled
상태의 프로미스를 반환한다.
then, catch 는 원활한 체이닝을 위해 항상 프로미스를 반환한다.
이 과정에서 다음의 규칙을 따른다.
- 반환 값이 프로미스라면 해당 프로미스를 그대로 반환한다.
- 반환 값이 프로미스가 아니라면 해당 값을 데이터로 가지며 fulfilled 상태인 프로미스를 반환한다.
결과적으로 'Error 1'
을 출력한 뒤 다음 then으로 이동한 뒤 'Success 4'
를 출력하며 종료된다.
정답은 Error 1, Success 4
가 된다.
2번
function job(state) {
return new Promise(function(resolve, reject) {
if (state) {
resolve('success');
} else {
reject('error');
}
});
}
let promise = job(true);
promise
.then(function(data) { // A
console.log(data);
return job(false);
})
.catch(function(error) { // B
console.log(error);
return 'Error caught';
})
.then(function(data) { // C
console.log(data);
return job(true);
})
.catch(function(error) { // D
console.log(error);
});
이번 job은 인자로 받는 state 값에 의해 'success'
를 resolve하거나 'error'
을 reject하는 프로미스를 반환한다.
첫 promise는 success를 resolve하는 프로미스이다.
이에 따라 A
에 의해 'success'
를 출력 하며 'error'
을 reject하는 프로미스를 반환한다.
B
에 의해 rejected
되어 'error'
을 출력 하고 'Error caught'
를 반환한다.
'Error caught'
문자열을 데이터로 갖는 프로미스가 반환되고 C
에 의해 'Error caught'
를 출력 하고 'success'
을 resolve하는 프로미스를 반환한다.
이후 체이닝에는 then이 존재하지 않기 때문에 종료된다.
즉, 정답은 success, error, Error caught
가 된다.
3번
function job(state) {
return new Promise(function(resolve, reject) {
if (state) {
resolve('success');
} else {
reject('error');
}
});
}
let promise = job(true);
promise
.then(function(data) { // A
console.log(data);
return job(true);
})
.then(function(data) { // B
if (data !== 'victory') {
throw 'Defeat';
}
return job(true);
})
.then(function(data) { // C
console.log(data);
})
.catch(function(error) { // D
console.log(error);
return job(false);
})
.then(function(data) { // E
console.log(data);
return job(true);
})
.catch(function(error) { // F
console.log(error);
return 'Error caught';
})
.then(function(data) { // G
console.log(data);
return new Error('test');
})
.then(function(data) { // H
console.log('Success:', data.message);
})
.catch(function(data) { // I
console.log('Error:', data.message);
});
job은 2번과 같다.
A
에 의해 'success'
을 출력 하고 'success'
을 resolve하는 프로미스를 반환한다.
B
에서 data는 'success'
값을 갖는다.
'success' !== 'victory'
는 참이므로 'Defeat'
을 throw 한다.
(throw에 의해 밑에 있는 return은 실행되지 않는다.)
B
에서 throw된 예외는 D
에 의해 처리 된다. 이 때 error은 'Defeat'
값을 갖는다.
따라서, 'Defeat'
을 출력 하고 'error'
을 reject하는 프로미스를 반환한다.
이는 F
에 의해 처리되고 'error'
을 출력 하고 'Error caught'
을 데이터로 갖는 프로미스를 반환한다.
이는 G
에서 'Error caught'
을 출력 하며 new Error('test')
을 데이터로 갖는 프로미스를 반환한다.
여기서 Error을 반환했다는 이유로 예외라고 생각하면 안된다.
그저 Error 객체를 생성한 것 뿐이고 예외가 발생한 것이 아니다.
따라서 Error 생성자에 의해 생성된 객체를 데이터로 갖는 프로미스가 반환된다.
이는 H
에 의해 'Success: test'
을 출력 하며 함수가 종료된다.
정답은 success, Defeat, error, Error caught, Success: test
가 된다.
new Error을 throw 하지 않아서 then에 의해 처리되는 것이 살짝 헷갈릴 수 있는 부분이라고 생각한다.
'유연해지기 > Javascript' 카테고리의 다른 글
JavaScript Set 내 맘대로 구현하기 (1) | 2022.11.30 |
---|---|
Vanilla Javascript로 간단한 SPA 라우터 구현해보기 (4) | 2022.05.13 |
[Javascript] Iterable, 반복자 그리고 생성자 함수에 대하여 (0) | 2021.09.27 |
[Javascript] 자바스크립트 Map 정렬하기 (0) | 2021.05.03 |