일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- javascript
- scflix
- Nomad coder
- react-native
- coding
- Netflix
- Firebase
- CSS
- react-hook
- github
- 프로젝트
- 느낀 점
- expo
- Vanilla
- 계획
- 자바스크립트
- Hook
- 코코아톡
- 마무리
- Clone
- vanilla js
- Nomad
- 클론코딩
- TiMER
- react
- Nicolas
- 오류
- HTML
- Project
- 바닐라 자바스크립트
- Today
- Total
꾸매코딩
[JavaScript] Promise(프로미스) 란 무엇인가? 본문
프로미스(promise)를 이해하기 위해서는 JavaScript가 어떤 식으로 작동하는지 알아야 한다.
싱글 쓰레드 언어인 JavaScript는 비동기 처리를 위해서 콜백(Call Back)을 이용해 이를 보완하였다.
하지만 Call Back이 중첩되면서 코드의 복잡도가 증가하고, 예외처리에 어려움이 생기기 시작했다.
이러한 점을 보안하기 위해 프로미스(promise)가 만들어졌다.
비동기 처리
특정 코드의 실행이 완료될 때까지 기다리지 않고 다음 코드를 먼저 실행함.
비동기 처리 예 - setTimeout()
// 1
console.log("First");
// 2
setTimeout(() => {
console.log("Second")
}, 3000)
// 3
console.log("Third")
위에서 아래로 실행되는 JavaScript 특성상
- 'First' 출력
- 3초 대기, 'Second' 출력
- 'Third' 출력
이러한 결과가 나와야 한다. 하지만 실제로는
- 'First' 출력
- 'Third' 출력
- 3초 대기, 'Second' 출력
비동기 처리 방식에 의하여 위와 같은 결과가 나온다.
Promise
Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다. [MDN]
→ 내가 아직 모르는 Value값과 함께 작업할 수 있도록 도와줌
promise를 통해 콜백 중첩을 해결
내부적으로 예외처리 구조가 탄탄하기 때문에 오류 처리에 용의
new Promise 메서드를 호출할 때 resolve, reject를 인자로 콜백 함수를 선언할 수 있음.
new Promise((resolve, reject){
//...
});
Promise의 상태(states)
- 대기(pending): 이행하거나 거부되지 않은 초기 상태.
- 이행(fulfilled): 연산이 성공적으로 완료됨.
- 거부(rejected): 연산이 실패함.
대기(pending)
new Promise() 메서드를 호출하면 대기(pending) 상태가 된다.
new Promise();
이행(fulfilled) ≒ 완료
콜백 함수 인자 resolve를 통해 이행할 수 있고, then()을 이용하여 처리한다.
const getText = new Promise((resolve, reject) => {
resolve("result")
})
getText.then(text => console.log(text)) // result
거부(rejected)
콜백 함수 인자 reject를 통해 이행할 수 있고, catch()를 이용하여 에러를 처리한다.
const getText = new Promise((resolve, reject) => {
reject("error")
})
getText.catch(text => console.log(text)) // error
Promise 사용 방법
Promise는 보통 Api를 불러올 때 사용된다. (불러오는 data를 기다리고 그 data를 이용해야 하기 때문)
if와 비슷하게 then 실행 후 만족하지 않으면 catch를 실행하는 방식이 아니다.
then과 catch는 서로 다른 상황에서 실행되며, 동시에 실행될 수는 없다.
const getText = new Promise((resolve, reject) => {
setTimeout(resolve, 3000, "I'm result");
});
getText
.then((result) => console.log(result))
.catch((error) => console.log(error));
프로미스 연결하기 (Chaining Promise)
then() 메서드를 호출하면 새로운 프로미스 객체가 반환된다. 따라서 then 끼리 연결하여 사용 가능하다.
const getNumber = new Promise((resolve, reject) => {
resolve(2);
});
getNumber.then(number => number * 2)
}).then(otherNumber => {
console.log(otherNumber * 2) // 8
return otherNumber * 2
}) // 예시
.then((aa)=>{
return bb
}).then((bb)=>{
return cc
})
return 된 값은 다음 then의 인자 값으로 받아서 사용한다.
연결된 프로미스 에러 처리
연결되어 있는 프로미스도. catch()를 통해 처리가 가능하다.
const getNumber = new Promise((resolve, reject) => {
resolve(2);
});
getNumber.then(number => number * 2)
.then(otherNumber => otherNumber * 2)
.then(() => {
throw Error("Error"); // 강제로 예외 발생
})
.then(lastNumber => console.log(lastNumber))
.catch(error => console.log(error)) // error 출력
연결된 프로미스중 하나라도 예외가 발생하면 실행이 안되고. catch() 구문이 실행된다.
Promise.all
불러야 할 API가 여러 개일 경우 사용할 수 있다.
const p1 = new Promise((resolve) => {
setTimeout(resolve, 3000, "First");
});
const p2 = new Promise((resolve, reject) => {
setTimeout(resolve, 2000, "second");
});
const p3 = new Promise((resolve) => {
setTimeout(resolve, 1000, "third");
});
const allPromise = Promise.all([p1, p2, p3]); // 배열 형태로 저장
allPromise
.then((value) => console.log(value));
.catch((error) => console.log(error));
가장 마지막에 완료되는 p1이 끝나면 p1, p2, p3는 배열의 형태로 allPromise에 저장된다.
각각의 Promise에 .then() 과 .catch()를 하는 반복을 줄일 수 있다.
참고자료
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://programmingsummaries.tistory.com/325
https://joshua1988.github.io/web-development/javascript/promise-for-beginners/