콜백에 대해서 간단히 공부하고 난 후에는 이제는 프로미스에 대해서 배울 차례입니다. 프로미스는 콜백함수가 계속해서 연결되는 경우, 코드도 보기 힘들어지고 계속 물고 늘어지기 떄문에 에러가 발생할 가능성이 높아지는데 이에 대한 해결책으로 나온 것입니다.
function increase (n, callback) {
setTimeout(() => {
const increased = n + 1;
console.log(increased);
if (callback) { // 콜백함수가 있다면
callback(increased); //매개변수에 n+1을 넣어라
}
}, 1000); //1초 뒤에 실행
}
increase(0, n => {
increase(n, n => {
increase(n, n => {
increase(n, n=> {
})
})
})
})
이런 식으로 콜백함수에 또 콜백함수를 넣고 또 넣고 해서, 차례대로 1씩 더하면서 출력할 것입니다.
프로미스를 쓰는 이유는 결국 가시성을 좋게하여 코드의 유지 보수를 좀 더 효율적이게 하기 위함입니다.
const promise = new Promise((resolve, reject) => {})
or
function promise () {
return new Promise((resolve, reject) => {});
}
프로미스 객체는 인스턴스 생성처럼 new 키워드와 생성자를 통해 객체를 생성합니다. 그리고 두개의 함수를 인자로 받습니다.(resolve, reject)
위의 그림에 보면 state: 에 3가지 상태가 있습니다. 각각 Pending(대기), Fulfilled(이행), Rejected(실패)를 나타냅니다. 이러한 상태를 두면 조건문 처럼 성공했을 때 실패했을 때 각각 분리해서 처리할 수 있습니다.
function devide(numA, numB) {
return new Promise((resolve, reject) => {
if (numB === 0) {
reject(new Error("fail"));
}
else {
setTimeout(() => reslove(numA / numB), 1000))
}
});
}
아직 생성자를 만들어 매개변수를 넣기 전이기 때문에 devide의 상태는 pending(대기) 상태입니다.
devide(4, 2)
.then((result) => console.log("성공", result))
.catch((error) => console.log("실패", error));
4가 2로 나누어져서 resolve가 1초뒤에 실행되었고 매개변수가 then으로 받아와서 출력함을 볼 수 있습니다.
devide(8, 0)
.then((result) => console.log("성공", result));
.catch((error) => console.log("실패", error));
numB가 0이기 떄문에 catch() 메서드가 호출되었고 fail을 반환하고 "실패"를 출력합니다.
promise.then(
function(result) {} // 첫 번쨰 인수는 프라미스가 이행되었을 떄 실행되는 함수, 실행 결과를 받음
function(error) {} // 두 번쨰 인수는 프라미스가 거부되었을 때 실행되는 함수, 에러를 받음
)
상황에 따라 promise를 여러 번 사용해야하는 경우가 존재합니다.
new Promise(function (resolve, reject) {
setTimeout( () => resolve(1), 1000);
}).then(function(result) {
return result * 2
}).then(function (result) {
return result *2
}).then(function (result) {
return result *2
})
반환 값이 넘어가면서 최종적으로는 8이 반환됨
cook()
.then(function() {
return readytofood()
})
.then(function() {
return cookFood
})
.then(function() {
return settingFood
})
연속적으로 사용하여 순차적인 작업도 할 수 있음
마지막 catch 구문에서 모든 에러를 한번에 처리가 가능
goToSchool() .then(function(){ return arriveAtSchool(); }) .then(function(){ return studyHard(); }) .then(function(){ return eatLunch(); }) .catch(function(){ leaveEarly(); });
출처: https://sangminem.tistory.com/284 [미리 알았다면 좋았을 텐데]
promise 클래스에는 5가지 정적 메서드가 있습니다.
Promise.all([
new Promise(resolve => setTimeout(() => resolve(1), 3000)),
new Promise(resolve => setTimeout(() => resolve(2), 2000)),
new Promise(resolve => setTimeout(() => resolve(3), 1000))
]).then(alert);
에러가 있는 경우 allPromise에 대해서 해주면 됨
const p1 = new Promise((resolve, reject) => {
setTimeout(reject, 2000, "First reject");
})
const p2 = new Promise(resolve => {
setTimeout(resolve, 1000, "Second");
})
const p3 = new Promise(resolve => {
setTimeout(resolve, 3000, "Third");
})
const allPromise = Promise.all([p1,p2,p3]);
allPromise
.then(values => console.log(values))
.catch(error => console.log(error));
// First reject
가장 먼저 처리되는 프라미스의 결과를 반환
Promise.race([
new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)),
new Promise((resolve, reject) => setTimeout(() => reject(new Error("에러 발생!")), 2000)),
new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000))
]).then(alert); // 1