Promise란?
Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결괏값을 나타냅니다. MDN
ES6에서 추가된 Promise는 비동기 연산을 하기 위한 객체이며 기존의 callback 함괏의 단점들을 보완한 함수입니다.
Promise는 다음 중 하나의 상태를 가집니다.
- 대기(pending): 이행하거나 거부되지 않은 상태
- 이행(fulfilled): 연산이 성공적으로 완료됨.
- 거부(rejected): 연산이 실패함.
Promise의 사용방법
Promise는 resolve, reject 두 인자를 매개변수로 받습니다. 이 두 함수는 promise를 이행하거나 거부합니다. 비동기 작업이 모두 끝난 뒤 resolve를 호출해서 이행하고, 오류가 생겼다면 reject를 이용하여 거부할 수 있습니다. 또한 Promise 객체에는 비동기 상태가 담겨있기 때문에 비동기 처리 시점을 명확하게 표시할 수 있습니다.
const promise = new Promise((resolve, reject) => {})
console.log(promise) // Promise {status: "pending"}
then, catch, finally
Promise가 종료되면 then과 catch로 resolve와 reject의 값을 꺼내어 볼 수 있습니다. 하지만 reject 된 경우에는 catch 항목이 없다면 오류가 발생합니다.
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("성공"), 1000)
}) // 10초 후에 결과 출력
promise1.then(console.log) // 성공
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => reject("실패"), 1000)
}) // 10초 후에 결과 출력
promise2.then(console.log) // 오류가 발생했지만 catch 항목이 없어서 error 발생
// Uncaught (in promise) 실패
promise2
.then(console.log)
.catch(console.error) // 실패
.finally(() => console.log("종료됨")) // 이행이나 거부와 상관없이 무조건 실행됨
메서드 체이닝
Promise의 리턴값은 자기 자신을 반환하기 때문에 함수를 연속적으로 사용할수 있습니다. 또한 연속적으로 사용한 함수에서 에러처리 또한 매번 할 필요 없이 한번만 처리 해주면 됩니다.
const promise = new Promise((resolve, reject) => resolve(1));
const add1 = (num) => num + 1;
promise
.then(add1)
.then(add1) // 연속적으로 then 호출 가능
.then(console.log);
.catch(console.error); // 연속적으로 then을 호출하더라도 하나의 catch에서 처리
Promise.all, Promise.rece
Promise 메서드 종류
- Promise.all: 주어진 모든 Promise를 이행합니다.
- Promise.rece: 주어진 모든 Promise 중 가장 먼저 완료된 것만 이행합니다.
// Promise.all
const promise1 = new Promise((resolve) => setTimeout(resolve, 3000, "첫번째"))
const promise2 = new Promise((resolve) => setTimeout(resolve, 2000, "두번째"))
const promise3 = new Promise((resolve) => setTimeout(resolve, 1000, "세번째"))
const allPromise = Promise.all([promise1, promise2, promise3])
allPromise
.then(console.log) // 모든 promise를 이행한뒤 출력
.catch(console.error)
// [ '첫번째', '두번째', '세번째']
// Promise.rece
const promise1 = new Promise((resolve, reject) => setTimeout(reject, 3000, "첫번째"))
const promise2 = new Promise((resolve) => setTimeout(resolve("두번째"), 2000))
const promise3 = new Promise((resolve) => setTimeout(resolve("세번째"), 1000))
const recePromise = Promise.race([promise1, promise2, promise3])
recePromise
.then(console.log) // 가장 먼저 끝난 세번째만 반환하고 종료
.catch(console.error) // 첫번째가 이행되지 않아서 오류발생안함
// [ '세번째']