promise(in JavaScript)
promise ; 약속, 자바스크립트에서 비동기 간편하게 처리할 수 있게 하는 오브젝트
정해진 기능 수행하고 나서 정상적으로 기능이 수행되면 성공의 메세지와 함께 결과값을 전달
만약 기능을 수행하다가 예상치 못한 문제가 발생하면 에러를 전달
예를들어 준비중인 강의가 언제 오픈될지 모르는 데 관심학생은 미리 등록하는 시스템에서 사용.
시간 지난 후 코스가 오픈되면 등록한 학생에게 메일 공지를 보냄
수업이 이미 오픈된 뒤에 철수가 뒤늦게 사전공지 창을 발견
뒤늦게 등록하지만 수업이 이미 오픈되었기 때문에 기다릴 필요없이 바로 메일 공지
수업에 바로 참여 가능해짐
콜백을 쓰지 않고 프로미스 오브젝트를 통해 비동기 코드 깔끔하게 처리하기
프로미스는 자바스크립트 안에 내장되어진 오브젝트
비동기적인 것을 처리할때 콜백함수 대신 유용하게 쓸 수 있음
포인트 2가지
1. State
pending state
수행중
fulfiled state
수행완료, 수행 다 완료해서 성공했는지 실패했는지
rejected
파일을 찾을수없거나 네트워크에 문제
2. producer 와 consumer 의 차이점 알기
Producer
원하는 기능을 수행해서 해당하는 데이터를 만들어내는, 데이터를 제공하는
Consumer
원하는 데이터를 소비하는, 제공된 데이터를 쓰는
1. Promise 만들기
1. Producer
원하는 기능을 비동기적으로 실행하는 프로미스 만들기
기능을 정상적으로 수행해서 최종 데이터를 전달하는 resolve
기능을 수행하다가 중간에 문제가 생기면 호출하는 reject
위 두가지를 받는 콜백함수를 인자로 받음
네트워크에서 데이터를 받거나, 파일에서 무언가 큰 데이터를 읽어오는 과정은
시간이 꽤 걸림 그런걸 동기적으로 처리하면 다음 라인코드가 실행되지 않기에
시간걸리는건 비동기적으로 처리하는게 좋음
따라서 네트워크 처리, 파일읽기는 비동기적으로 처리하는게 좋다.
위코드 실행시 바로 doing something 이 출력됨
=프로미스를 만드는 순간 전달한 콜백함수가 바로 자동적으로 실행됨 유의 !!
프로미스 안에 네트워크 통신을 하는 코드를 작성했다면
프로미스가 만들어 지는 순간 바로 네트워크 통신을 수행하게 됨
= 만약 네트워크 요청을 사용자가 요구했을때만 해야된다면 이런식으론
요구하지도 않았는데 불필요한 통신이 일어나게 됨
프로미스 안에서 네트워크 통신을 하는 것처럼 셋타임아웃을 이용해서 시간딜레이주기
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//1.producer
const promise = new Promise((resolve, reject) => {
//doing somet hard work...
console.log('doing something');
setTimeout(() => {
resolve('min');
}, 2000);
});
|
cs |
어떤 일을 2초정도 하다가 잘 마무리해서 resolve 콜백함수 호출해서 min 이 라는 데이터전달
2. promise 사용하기
then, catch, finally 를 통해 값을 받아 올 수 있음
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
//1.producer
const promise = new Promise((resolve, reject) => {
//doing somet hard work...
console.log('doing something');
setTimeout(() => {
resolve('min');
}, 2000);
});
//2. consumer(then, catch, finally)
promise.then((value)=>{
console.log(value);
});
|
cs |
promise 가 잘 수행하면 값을 받아서 어떠어떤일을 할거야
value는 promise가 잘 수행해서 resolve 콜백함수에서 전달된 min이라는 데이터
min 이 출력됨
프로미스가 정상적으로 수행되어서 resolve 라는 콜백함수를 통해서 전달한 값이
value 파라미터로 전달되어져서 들어오게 됨
만약 네트워크하다가 실패해서 reject를 호출한다면?
보통 error오브젝트 통해 값을 전달
error 클래스는 자바스크립트에서 제공하는 오브젝트
보통 error 오브젝트에는 어떤에러가 발생했는지 이유를 작성함
then으로 성공적인 케이스만 다뤘기에 잡히지않았다(uncaught) 의
위와 같은 에러가 뜨게됨
=> catch를 이용해 에러발생시 처리를 다루기
위와 같이 에러가 콘솔에 출력됨
finally
성공하던 실패하던 상관없이 무조건 마지막에 호출됨
3. promise 연결하기
5가 출력됨
then에서 return을 또 promise로 할 수 있음
4. 오류 처리하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
//4. Error handling
const getHen = ()=>
new Promise((resolve, reject)=>{
setTimeout(()=> resolve('chicken'), 1000);
});
const getEgg = hen =>
new Promise((resolve, reject)=>{
setTimeout(()=> resolve(`${hen}=> egg`),1000);
});
const cook = egg =>
new Promise((resolve, reject)=>{
setTimeout(()=> resolve(`${egg}=> fried egg`),1000);
});
getHen()
.then(hen => getEgg(hen))
.then(egg => cook(egg))
.then(meal => console.log(meal));
|
cs |
chicken=> egg=> fried egg 출력
만약 달걀을 받아오는 과정에서 네트워크에 문제가 생겨 실패한다면?
(getEgg부분)
맨 밑에 .catch를 붙이면, 에러가 발생했지만 에러가 젤 밑으로 전달되며 잡혀짐
달걀을 받아올때 문제가 생긴다면 다른재료로 대체 하고싶다면?
getEgg에 문제가 생겨도 전체적인 프로미스 체인에 문제가 발생하지 않도록
위에서 발생하는 문제 대처하기 위해 아래에 catch를 바로작성해서 바로해결
catch 위치가 위와 같은 경우에는 bread 가 출력
5. 콜백 헬을 프로미스로 재단장
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
class UserStorage{
loginUser(id, pass){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
if(
(id==='min'&& pass==='dream') ||
(id==='coder'&& pass==='great')
){
resolve(id);
}else{
reject(new Error('not found'));
}
},2000);
});
}
getRoles(user){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
if(user==='min'){
resolve({name : 'min', role : 'admin'})
}else{
reject(new Error('no access'));
}
}, 1000);
})
}
}
const userStorage = new UserStorage();
let id = prompt('what is your id ? ');
let password = prompt('what id your password?');
userStorage.loginUser(id, password)
.then(userStorage.getRoles)
.then((user)=> alert(`hello ${user.name} your role is ${user.role}`))
.catch(console.log)
|
cs |
좌 ;프로미스 사용 우; 콜백지옥