Promise는 JavaScript의 비동기 처리에 사용되는 객체입니다. 비동기 작업이 끝난 후 나온 결과에 대해 성공 및 실패의 내용을 나타내는데 사용됩니다.
비동기 작업은 일반적으로 네트워크 요청을 보내거나 파일을 읽는 등의 작업을 포함합니다. 이러한 작업들은 상황에 따라 작업이 완료되기 전에 다른 코드가 실행되어 문제가 발생되는데 Promise를 사용한다면 문제 없이 비동기 작업을 처리할 수 있습니다.
Promise 객체는 크게 2가지의 값을 가집니다. 비동기 작업의 결과물(result)와 결과의 상태(state)입니다.
Promise는 아래와 같이 총 3가지의 상태를 가질 수 있습니다.
Promise는 생성자 함수를 통해 사용할 수 있습니다. 위의 코드와 결과창을 살펴보면 현재 Promise는 대기(Pending) 상태를 확인 할 수 있습니다.
이행(Fulfilled) 상태일 때
Promise 객체를 생성할 때 resolve와 reject라는 함수 형태의 매개변수 2개를 받습니다. 그 중에서 resolve는 성공 했을 때 완료되었음을 알립니다. 결과창을 살펴보면 'pending'이던 PromiseState가 'fulfilled'로 변했고 'undefined'인 PromiseResult가 data 변수의 값으로 채워진걸 볼 수 있습니다.
거부(Rejected) 상태일 때
예시 코드를 변경하여 의도적으로 Promise가 실패하는 상황을 만들었습니다. reject에 오류가 난 내용을 채웠으며 결과창을 확인하면 PromiseState는 'rejected'가, PromiseResult에는 Error 객체가 채워져 있는걸 확인할 수 있습니다.
위의 내용은 비동기 함수를 '구현'하는 입장에서 Promise를 봐았다면 이번에는 Promise를 반환하는 비동기 함수를 사용하는 입장에서 살펴보겠습니다.
먼저 Promise 객체에서는 여러가지 api를 제공합니다. 그 중 비동기 작업에 대한 후처리를 도와주는 then(), catch(), finally()에 대해 설명하겠습니다.
then()은 promise의 비동기 작업이 끝난 후 이행(Fulfilled) 상태가 되었을 때 안에 있는 콜백 함수를 호출하게 됩니다. 즉, 성공적인 작업 이후의 처리를 할 수 있다는 것입니다. then이 받는 매개변수는 promise의 결과값을 담고 있습니다.
promise.then((result) => { // 성공적으로 이행된 경우의 처리 })
catch()은 비동기 작업을 처리하는 중에 문제가 발생하여 Promise가 실패하면 다음 후처리를 도와줍니다.
promise.then((result) => { // 성공적으로 이행된 경우의 처리 }).catch((error) => { // 실패한 경우의 처리 });
finally()은 Promise가 성공하든 실패하든 반드시 해야하는 작업이 있을 경우 사용하는 api입니다.
promise.then((result) => { // 성공적으로 이행된 경우의 처리 }).catch((error) => { // 실패한 경우의 처리 }).finally(() => { // 반드시 해야하는 작업 });
예시 코드 처럼 사용할 수 있습니다.
fetch 함수는 네트워크 요청을 보내고 응답을 받는 비동기 작업을 수행하는데 사용됩니다. 또한 fetch 함수는 Promise 객체를 반환하기 때문에 Promise의 api를 사용할 수 있습니다.
위의 예시 코드를 보면 then()를 사용 후 then()를 사용하는 것을 볼 수 있습니다. then()은 항상 Promise 객체를 반환하게 되는데 이런 이유 때문에 then() 다음에 then()을 이어서 사용할 수 있는데 이것을 우리는 'Promise Chaninin'이라고 합니다.
'Promise Chanining'를 사용하게 되면 비동기 작업이 완료된 후에 다음 비동기 작업을 수행을 쉽게 할 수 있고 여러가지 장점이 존재합니다.
비동기 작업의 순서 보장
이전 작업이 완료되기 전에 다음 작업이 시작되지 않도록 구조화
코드 재사용
비슷한 비동기 작업이 반복될 때, 같은 로직을 반복해서 작성할 필요 없이 기존에 작성한 프로미스를 재사용