https://www.codingame.com/playgrounds/347/javascript-promises-mastering-the-asynchronous
Coding Games and Programming Challenges to Code Better
CodinGame is a challenge-based training platform for programmers where you can play with the hottest programming topics. Solve games, code AI bots, learn from your peers, have fun.
www.codingame.com
간단한 프로미스 퀴즈가 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 |