할머니의 콤퓨타 도전기
(JavaScript) Promise 본문
Promise
- Promise is a JavaScript object for asynchronous operation.
- State : pending(promise가 만들어져서 지정한 operation이 수행중일 때) -> fulfilled(operation을 성공적으로 끝냄) or rejected
- Producer(원하는 기능을 수행해서 해당하는 데이터를 만들어냄) vs Consumer(원하는 데이터를 소비함)
Producer
- when new Promise is created, the executor runs automatically.
- promise를 만드는 순간 우리가 전달한 executor 콜백함수가 바로 실행
- promise를 만드는 순간 우리가 전달한 executor 콜백함수가 바로 실행
- 만약 네트워크 요청을 사용자가 요구했을 때만(ex. 버튼을 눌렀을 때) 해야하는 경우라면 아래처럼 작성하면 요구하지도 않았는데 불필요한 네트워크 통신 발생
- 네트워크에서 데이터를 받아오거나 파일에서 큰 데이터를 읽어오는 과정은 시간이 꽤 걸림
- 따라서 이를 synchronous로 처리하게 되면 데이터를 받아오거나 읽어오는 동안 다음 라인의 코드가 실행되지않음
- 시간이 걸리는 일들은 promise를 만들어서 비동기적으로 처리하는 것이 좋음
const promise = new Promise((resolve, reject) => {
// Promise는 class이기 때문에 new keyword로 object 생성
// Promise의 생성자는 executor라는 콜백함수 전달해줘야힘
// executor는 또 다른 2가지의 콜백함수를 받음
// resolve -> 기능을 정상적으로 수행해서 마지막에 최종 데이터 전달
// reject -> 기능을 수행하다가 중간에 문제가 생기면 호출
// doing some heavy work (network, read files)
// 네트워크에서 데이터를 받아오거나 파일에서 큰 데이터를 읽어오는 과정은 시간이 꽤 걸림
// 따라서 이를 synchronous로 처리하게 되면 데이터를 받아오거나 읽어오는 동안 다음 라인의 코드가 실행되지않음
// --> 시간이 걸리는 일들은 promise를 만들어서 비동기적으로 처리하는 것이 좋음
console.log('doing something...');
// promise를 만드는 순간 우리가 전달한 executor라는 콜백함수가 바로 실행됨
// 만약 promise 안에 네트워크 통신을 하는 코드를 작성했다면,
// promise가 만들어지는 그 순간 바로 네트워크 통신 수행하게 됨
setTimeout(() => {
resolve('jiwon'); // 성공적으로 네트워크에서 받아오거나 파일에서 읽어온 데이터를 resolve 콜백함수를 통해 전달
}, 2000);
});
Consumers
- then, catch, finally
- then
- promise가 정상적으로 수행이되어서 마지막에 최종적으로 resolve 콜백함수를 통해서 전달한 값이 value의 파라미터로 전달되어짐
- then
promise.then((value) => { // 값이 정상적으로 수행이 된다면
console.log(value); // value: promise가 정상적으로 잘 수행이되어서 마지막으로 resolve 콜백함수에서 전달된 값이 들어옴
}) // then을 호출하게 되면 다시 promise가 return되므로 catch 등록 가능
.catch(error => {
console.log(error);
})
.finally(() => { // finally: 성공 실패 여부 상관없이 마지막으로 수행
console.log('finally');
});
Promise chaining
const fetchNumber = new Promise((resolve, reject) => {
setTimeout(() => resolve(1), 1000);
});
fetchNumber.then(num => num * 2)
.then(num => num * 3)
.then(num => {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num - 1), 1000);
});
})
.then(num => console.log(num)); // 5
// then : 값을 바로 전달할 수도 있고, promise 전달도 가능
Error Handling
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) // 콜백함수를 전달할 때, 받아오는 value를 다른 함수로 호출하는 경우 생략 가능 hen => getEgg(hen)
.catch(error => {
return '🍞'; // 전달되어진 에러를 잘 처리해서 대체
}).then(cook)
.then(console.log)
.catch(console.log);
콜백함수를 전달할 때, 받아오는 value를 다른 함수로 호출하는 경우 생략이 가능하다.
마지막으로 이전 포스팅에서 Callback hell을 작성했다. promise를 이용해 이를 수정할 수 있다.
class UserStorage {
loginUser(id, password) { // 콜백 더이상 전달받지 않아도 됨
return new Promise((resolve, reject) => {
setTimeout(() => {
if ((id === 'jiwon' && password === '1234') ||
(id === 'coder' && password === '0000')
) {
resolve(id);
} else {
reject(new Error('not found'));
}
}, 2000);
});
};
getRoles(user) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (user === 'jiwon') {
resolve({ name: 'jiwon', role: 'admin' });
} else {
reject(new Error('no access'));
}
}, 1000);
});
}
}
// 1. 사용자에게 id, password 입력받아옴
// 2. 받아온 id, password로 login
// 3. login이 성공적이라면 login한 사용자의 id를 다시 받아옴. 받아온 id를 이용해 역할 요청
// 4. 역할이 성공적으로 받아와진다면, 사용자의 object를 받아옴. 이를 출력
const userStorage = new UserStorage();
const id = prompt('enter your id');
const password = prompt('enter your password');
userStorage.loginUser(id, password)
.then(userStorage.getRoles)
.then(user => alert(`Hello ${user.name}, you have a ${user.role} role`))
.catch(console.log);
'Web Front-end > Javascript' 카테고리의 다른 글
JavaScript 최신 문법 (ES6, ES11) (0) | 2021.05.05 |
---|---|
(JavaScript) async & await (0) | 2021.05.05 |
(JavaScript) Callback (0) | 2021.05.05 |
(JavaScript) JSON (0) | 2021.05.05 |
(Javascript) Array APIs (0) | 2021.05.04 |
Comments