Promise is a JavaScript object for asynchronous operation.
(비동기적인 것들을 실행 할 때 CallBack 함수 대신 유용하게 쓸 수 있는 object)
Promise의 두가지 Point
pending(operating 수행 중일 때) -> fulfilled or rejected(operating 완료 되었을 때)
- 비동기적으로 일을 처리하는 Promise 생성
- executor라는 CallBack 함수 전달해 주어야함
- promise를 만드는 순간 우리가 전달한 executor(resolve, reject) 라는 callback함수가 바로 실행
- when new Promise is created, the executor runs automatically. -> 불필요한 network 통신 발생하지 않도록 주의
var Promise: PromiseConstructor
new <any>(executor: (resolve: (value: any) => void, reject: (reason?: any) => void) => void) => Promise<any>
const promise = new Promise((resolve, reject) => {
// doing some heavy work (ex. network, read files)
conmsole.log('doing something');
// 데이터 가저오는 시간 가정
setTimeout(() => {
// resolve('eelkom');
reject(new Error('no network')) // reject는 보통 Error라는 object를 통해 값을 전달
}, 2000);
});
promise
.then((value) => { // value == resolve의 전달 값이 들어감
console.log(value); // eelkom
}) // then은 promise를 return == chaining
.catch(error => {
console.log(error); // Error: no network
})
.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);
});
})
.then(num => console.log(num)); // 5
const getHen = () =>
new Promise((resolve, reject) => {
setTimeout(() => resolve('chicken'), 1000);
});
const getEgg = hen =>
new Promise((resolve, reject) => {
// setTimeout(() => resolve(`${hen} => egg`), 1000);
setTimeout(() => reject(new Error(`error! ${hen} => egg`)), 1000);
});
const cook = egg =>
new Promise((resolve, reject) => {
setTimeout(() => resolve(`${egg} => Fried egg`), 1000);
});
getHen() // chicken => egg => Fried egg
.then(getEgg) // == then(hen => getEgg(hen)) -> 생략가능
.catch(error => { // 오류 처리 잘하자
return 'bread';
}) // bread => Fried egg
.then(cook) // == then(egg => cook(egg))
.then(console.log) // == then(meal => console.log(meal))
.catch(console.log); // Error: error! chicken => egg
// 임시 back-end 구성
class UserStorage {
// back-end 통신시간 존재한다고 가정
loginUser(id, password, onSuccess, onError) {
setTimeout(() => {
if (
(id === 'eelkom' && password === 'lee') ||
(id === 'coder' && password === 'lee')
) {
onSuccess(id);
} else {
onError(new Error('not found'));
}
}, 2000);
}
getRoles(user, onSuccess, onError) {
setTimeout(() => {
if (user === 'eelkom') {
onSuccess({ name: 'eelkom', role: 'admin' });
} else {
onError(new Error('no sccess'));
}
}, 1000);
}
}
// back-end 불러오기
const userStorage = new UserStorage(); // class 생성
const id = prompt('enter your id');
const password = prompt('enter your password');
userStorage.loginUser(
id,
password,
(user) => {
userStorage.getRoles(
user,
(userWithRoles) => {
alert(`Hello ${userWithRoles.name}, you have a ${userWithRoles.role} role`);
},
(error) => {console.log(error)}
);
},
(erorr) => {console.log(error)}
);
// 임시 back-end 구성
class UserStorage {
// back-end 통신시간 존재한다고 가정
loginUser(id, password) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (
(id === 'eelkom' && password === 'lee') ||
(id === 'coder' && password === 'lee')
) {
resolve(id);
} else {
reject(new Error('not found'));
}
}, 2000);
});
}
getRoles(user) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (user === 'eelkom') {
resolve({ name: 'eelkom', role: 'admin' });
} else {
reject(new Error('no sccess'));
}
}, 1000);
});
}
}
// back-end 불러오기
const userStorage = new UserStorage(); // class 생성
const id = prompt('enter your id');
const password = prompt('enter your password');
userStorage.loginUser(id, password)
.then(userStorage.getRoles) // user => userStorage.getRoles(user)
.then(user => alert(`Hello ${user.name}, you have a ${user.role} role`))
.catch(console.log);