Promise
자바스크립트 안에서 제공하는 비동기를 간편하게 처리할 수 있도록 도와주는 object 이다.
- 정해진 장시간의 기능을 수행하고 나서, 정상적인 기능이 수행 되어졌다면 성공의 메시지와 함께 처리된 결과값을 전달한다.
- 기능을 수행하다가 예상치 못한 문제가 발생했다면 error를 전달해 준다.
- state (상태)
프로세스가 무거운 오퍼레이션을 수행하고 있는 중인지, 기능 수행이 완료되어서 성공했는 지 실패했는 지 상태에 대해 이해하는 것이 중요하다.
- 프로미스가 만들어져서 우리가 지정한 오퍼레이션이 수행 중일 때는 pending 상태가 된다.
- 오퍼레이션을 성공적으로 끝내게 되면 fulfilled 상태가 된다.
- 파일을 찾을 수 없거나 문제가 있다면 rejected 상태가 된다.
- producer와 consumer의 차이점
우리가 원하는 데이터를 제공하는 사람과, 제공된 데이터를 쓰는 사람 두 가지의 차이점을 이해하면 좋다.
정보를 제공하는 프로듀서와 소비하는 소비자의 견해를 이해해야 한다.
producer
const promise = new Promise((resolve, reject) => {
//조금 무거운 일들을 함, 파일에서 무언가를 읽어오는 과정 등
//시간이 꽤 걸리는 작업들을 해야함
//그래서 비동기적으로 시간이 걸리는 일들을 비동기적으로 처리 함
console.log("doing something");
});
만약 네트워크 요청을 사용자가 요구했을 때만 해야하는 경우라면 (사용자가 버튼을 눌렀을 때)
이런식으로 작성하면 불필요한 네트워크가 요청될 수 있음
그래서 promise를 만드는 순간부터 바로 실행이 되기 때문에 유의해야 한다.
새로운 프로미스를 만들 때는 전달한 executor가 바로 실행이 된다.
const promise = new Promise((resolve, reject) => {
//조금 무거운 일들을 함, 파일에서 무언가를 읽어오는 과정 등
//시간이 꽤 걸리는 작업들을 해야함
//그래서 비동기적으로 시간이 걸리는 일들을 비동기적으로 처리 함
console.log("doing something");
setTimeout(() => {
resolve('ellie');
}, 2000);
});
이렇게 promise를 만들어서 console도 출력하고 한 다음,
resolve라는 콜백함수를 호출하면서, ellie라는 값을 전달해주는 promise를 만들어 보았다.
consumer
이제 저렇게 resolve로 값을 전달해주는 promise를 만들었으니까 이제, 이것을 이용하는 promise를 사용하는 방법을 알아야 한다.
than, catch, finally를 이용해서 받아올 수 있다.
promise.then((value) => {
console.log(value);
});
이 than은 프로미스가 정상적으로 잘 수행이 되어서 마지막으로 resolve라는 콜백함수를 통해 전달한 값이 value라는 파라미터로 전달되어서 보여지는 것을 알 수 있다.
만약 우리가 reject를 사용하면 어떻게 될까?
console.log("doing something");
setTimeout(() => {
reject(new Error("no network"));
// resolve("ellie");
}, 2000);
});
promise
.then((value) => {
console.log(value);
})
.catch((error) => {
console.log(error);
});
프로미스 오브젝트를 만들 때, 비 동기적으로 수행하고 싶은 기능들의 코드를 작성하고 나서, 성공이라면 resolve를 호출하게 되고
실패했다면 reject와 왜 실패했는 지 받아올 수 있다.
resolve - than
reject - catch
promise
.then((value) => {
console.log(value);
})
.catch((error) => {
console.log(error);
})
.finally(() => {
console.log("finally");
});
마지막 finally는 promise의 성공과 실패와 관련없이 맨 마지막으로 실행되는 것이다.
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를 전달할 수도 있다.
프로미스의 핸들링으로 이렇게 닭을 받아와서 달걀을 만들고 달걀을 받아와서 후라이를 만드는 과정이 보여진다.
.then(getEgg)
.then(cook)
.then(console.log)
로 완전 간단하게 가능하다.
getHen() //
.then(getEgg)
.catch((error) => {
return "빵";
})
.then(cook)
.then(console.log)
.catch(console.log);
만약에 getEgg에서 오류가 나서 되지 않는다면, return으로 빵을 대신 받아올 수 있다.
바로 다음에 catch를 작성하면서 오류를 바로잡으면 된다.
callback 에서 했던 것 promise 형식으로 변환
class userStorage {
loginUser(id, password) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (
(id === "ellie" && password === "dream") ||
(id === "coder" && password === "coding")
) {
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 id = prompt("id please");
const password = prompt("password please");
const storage = new userStorage();
storage
.loginUser(id, password)
.then((user) => storage.getRoles)
.then((user) =>
console.log(`hi ${userRole.name}, your role is ${userRole.role}`)
)
.catch(console.log);
'JavaScript' 카테고리의 다른 글
javascript ES6, ES11 최신문법 정리 (0) | 2022.09.17 |
---|---|
javascript 비동기 프로그래밍 - async await / 유용한 promise APIs (0) | 2022.09.17 |
javascript 비동기 프로그래밍 - 콜백(callback) 이해하기 (0) | 2022.09.16 |
javascript JSON 개념 정리와 활용 방법 및 유용한 사이트 공유 (0) | 2022.09.16 |
javascript 유용한 10가지 배열 함수들. Array APIs 총정리 (0) | 2022.09.16 |