💡 promise를 이용해서 콜백 지옥을 무찔러보자!
promise
는 장시간에 기능을 수행하고 나서 정상적으로 기능이 수행이 되어졌다면 성공의 메세지와 함께 처리된 결과값을 전달해준다.promise
에 대해 예를 들어보자면>promise
가 강좌가 오픈되었다는 알림을 이메일로 보내준다. 하지만 1월 2일에 그 공지를 보고 이메일 주소 남긴 사람은 기다릴 필요가 없이 promise
가 바로 공지를 보내준다.promise
오브젝트는 Async Operation
을 위해 쓰인다.promise
를 공부할 때 잡고가야할 point!promise
는 class라서 new
라는 키워드를 이용해서 오브젝트를 생성할 수 있다.promise
를 만들어서 비동기적으로 처리하는 것이 좋다.executor
라는 resolve
콜백 함수가 바로 실행되는 것을 확인 할 수 있다.promise
를 만드는 순간 그 안에 executor
라는 콜백함수가 바로 실행이 되니까 이점을 조금 유의하면서 공부해야한다.// when new Promise is created, the executor runs automatically.
const promise = new Promise((resolve, reject) => {
// doing some heavy work (network, read files) <- 이런 일들은 비동기적으로 해결하는 것이 좋음
console.log('doing something...');
setTimeout(() => {
resolve('ellie'); // 성공했을 때
// reject(new Error('no network'));
// Error라는 클래스는 JS에서 제공하는 object 중에 하나이다.
}, 2000);
});
then
, catch
, finally
를 이용해서 값을 받아올 수 있다.promise
변수를 이용해서then
을 이용해서 최종적으로 resolve
라는 콜백함수를 통해서 전달한 이 값('ellie')이 value
의 파라미터로 전달되어서 들어오게 된다.promise
.then(value => {
console.log(value); // ellie
})
catch
함수를 이용해 에러가 발생했을 때 어떻게 처리할지 콜백함수를 작성한다.promise //
.then(value => {
console.log(value);
})
.catch(error => {
console.log(error);
})
promise
의 then
을 호출하게 되면 then
은 결국 똑같은 프로미스를 리턴하게 된다.promise
에 catch
를 다시 호출 할 수 있는 것이다.promise //
.then(value => {
console.log(value);
})
.catch(error => {
console.log(error);
})
.finally(() => {
console.log('finally');
});
const fetchNumber = new Promise((resolve, reject) => {
setTimeout(() => resolve(1), 1000);
});
fetchNumber
.then(num => num * 2) // 1*2 = 2
.then(num => num * 3) // 2*3 = 6
.then(num => {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num - 1), 1000); // 6 -1 = 5
});
})
.then(num => console.log(num)); // 5
then
은 값을 바로 전달해도 되고, 또 다른 비동기인 promise
를 전달해도 된다.then
을 여러개 묶어서 다른 비동기적인 아이들도 묶어서 처리할 수도 있다.const getHen = () =>
new Promise((resolve, reject) => {
setTimeout(() => resolve('🐓'), 1000);
});
const getEgg = hen =>
new Promise((resolve, reject) => {
setTimeout(() => resolve(`${hen} => 🥚`), 1000);
// setTimeout(() => reject(new Error(`error! ${hen} => 🥚`)), 1000);
});
const cook = egg =>
new Promise((resolve, reject) => {
setTimeout(() => resolve(`${egg} => 🍳`), 1000);
});
getHen() //
.then(hen => getEgg(hen))
.then(egg => cook(egg))
.then(meal => console.log(meal));
getHen() //
.then(getEgg)
.then(cook)
.then(console.log);
//
를 적어주면된다.const getHen = () =>
new Promise((resolve, reject) => {
setTimeout(() => resolve('🐓'), 1000);
});
const getEgg = (hen) =>
new Promise((resolve, reject) => {
// setTimeout(() => resolve(`${hen} => 🥚`), 1000);
// 네트워크 문제로 실패하게 된다면?
setTimeout(() => reject(new Error(`error! ${hen} => 🥚`)), 1000);
});
const cook = (egg) =>
new Promise((resolve, reject) => {
setTimeout(() => resolve(`${egg} => 🍳`), 1000);
});
getHen() //
.then(getEgg)
.then(cook)
.then(console.log);
getHen() //
.then(getEgg)
.then(cook)
.then(console.log)
.catch(console.log);
getHen() //
.then(getEgg)
.catch(error => {
return '🥖'; // 빵꾸처리
})
.then(cook)
.then(console.log)
.catch(console.log);
// Callback Hell example
class UserStorage {
loginUser(id, password) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (
(id === 'ellie' && password === 'dream') ||
(id === 'coder' && password === 'academy')
) {
resolve(id);
} else {
reject(new Error('not found'));
}
}, 2000);
});
}
getRoles(user) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (user === 'ellie') {
resolve({ name: 'ellie', role: 'admin' });
} else {
reject(new Error('no access'));
}
}, 1000);
});
}
}
const userStorage = new UserStorage();
const id = prompt('enter your id');
const password = prompt('enter your passrod');
userStorage
.loginUser(id, password)
.then(userStorage.getRoles)
.then(user => alert(`Hello ${user.name}, you have a ${user.role} role`))
.catch(console.log);