[JS] Promise 객체와 메서드

SuKong·2021년 4월 23일
3
post-thumbnail

🤔 Promise란?

Promise객체비동기 작업 이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.

동기와 비동기?

그렇다면 동기(Syncronous)비동기(Asynchronous)의 차이점도 간단히 정리해보겠습니다.

동기 란 요청과 결과가 동시에 일어난다는 것입니다. 요청을 하면 시간이 얼마가 걸리던지, 그 요청의 결과가 주어져야하고 요청이 끝나기 전까지 다른 작업은 실행할 수 없습니다.

비동기 란 요청과 결과가 동시에 일어나지 않을 거라는 것입니다. 즉 어떠한 요청을 보내면 그 요청이 끝날 때까지 기다리는 것이 아니라, 응답에 관계없이 바로 다음 동작이 실행되는 방식입니다.

비동기 방식이 필요한 이유는 다음과 같습니다.
웹페이지가 로딩될때 동기적으로 처리된다면, 코드의 중간에 실행시간이 긴 요청이 발생할 시 해당 코드 이후에 대한 화면이 로딩되지 않고, 사용자는 긴 로딩시간을 기다려야 하기 때문입니다.

따라서 비동기식으로 구현하기 위해서는 자바스크립트에 내장되어있는 Promise 객체 를 활용하거나 Async함수 를 활용해야 합니다.

Promise의 작동방식

Promise 객체를 활용해서 요청한 일이 수행된 이후의 상태에 따라 실행할 행위를 각각 정의해둘 수 있습니다.

먼저, Promise는 다음 중 하나의 상태를 가집니다.

  • 대기(pending): 이행하거나 거부되지 않은 초기 상태.
  • 이행(fulfilled): 연산이 성공적으로 완료됨.
  • 거부(rejected): 연산이 실패함.

Promise객체는 다음과 같이 선언할 수 있습니다.

const promise = new Promise((resolve, reject)=>{
    //executer
})

new Promise에 전달되는 함수는 executer라고 부릅니다.
executor의 인수 resolve와 reject는 자바스크립트가 자체적으로 제공하는 콜백함수입니다. resolve와 reject를 신경 쓰지 않고 executor 안 코드만 작성하면 되지만, executor에선 상황에 따라 인수로 넘겨준 콜백(resolve, reject)중 하나를 반드시 호출해야 합니다.

  • resolve(value)
    일이 성공적으로 끝난 경우, 그 결과를 나타내는 value와 함께 호출.
    state는 pending에서 fulfilled로, result는 value가 된다.
  • reject(error)
    에러 발생 시 에러 객체를 나타내는 error와 함께 호출.
    state는 pending에서 rejected로, result는 error가 된다.

Promise 메서드

1. then()

then은 Promise에서 활용하는 가장 기본적인 메서드입니다.

const promise = new Promise((resolve, reject)=>{
    resolve('성공시 반환하는 값');
})

promise
    .then(successReturn => {alert(successReturn)});

then메서드는 resolve함수가 실행될 경우 실행이되고, resolve함수에 인자로 넘겨준 값이 넘어오게됩니다.
.then의 첫 번째 인수는 프라미스가 이행되었을 때 실행되는 함수이고, 여기서 실행 결과를 받습니다.
.then의 두 번째 인수는 프라미스가 거부되었을 때 실행되는 함수이고, 여기서 에러를 받습니다.
작업이 성공적으로 처리된 경우만 다루고 싶다면, 두번째 인수를 생략하고 하나만 전달하면 됩니다.

위와같은 코드에서는 successReturn으로 '성공시 반환하는 값'이 넘어왔으며, 이 값을 alert할 것입니다.

2. catch()

const promise = new Promise((resolve, reject)=>{
    reject(new Error("에러 발생!"));
})

promise
    .catch(errorReturn => {alert(errorReturn)});

catch메서드는 reject함수가 실행될 경우 실행이되고, reject함수에 인자로 넘겨준 값이 넘어오게됩니다.
.catch의 인수는 프라미스가 거부되었을 때 실행되는 함수이고, 여기서 에러를 받습니다.
.then에서 첫번째 인수에 null을 넣고, 두번째 인수를 활용하는 방법 (.then(null, 실행함수)) 과 동일한데 문법이 단순하고 가독성이 높다는 장점이 있습니다.

3. finally()

promise의 성공, 실패 여부와 상관없이 promise의 처리가 완료되면 실행됩니다.
또한, finally핸들러는 자동으로 다음 핸들러에 결과와 에러를 전달하기 때문에 다음과 같이 활용할 수도 있습니다.

const promise = new Promise((resolve, reject) => {
    resolve('성공시 반환하는 값');
})

promise
    .finally(() => alert("프라미스가 준비되었습니다."))
    .then(result => alert(result));

4. all()

all() 은 매개변수로 여러개의 promise객체가 담긴 Array와 같이 순회가능한 객체를 받아옵니다.
인수로 받아온 순회 가능한 객체에 주어진 모든 프로미스가 이행한 후, 혹은 프로미스가 주어지지 않았을 때 이행하는 Promise를 반환합니다.
주어진 프로미스 중 하나가 거부하는 경우, 첫 번째로 거절한 프로미스의 이유를 사용해 자신도 거부합니다.

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});

// > Array [3, 42, "foo"]

위와같이 활용할 수 있습니다.

5. race()

race()도 all()과 마찬가지로 promise객체가 담긴 Array와 같이 순회가능한 객체를 받아옵니다.
순회 가능한 객체 내부의 promise객체들 중 가장 먼저 완료된 Promise객체를 반환합니다.

const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then((value) => {
  console.log(value);
  // Both resolve, but promise2 is faster
});
// > "two"

위와같이 먼저 실행이 완료되는 promise2의 객체를 반환하고, .then을 통해 해당 객체의 이행결과에 따른 행위를 수행합니다.


출처 :
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
https://ljtaek2.tistory.com/142
https://ko.javascript.info/promise-basics

profile
안녕하세요 🤗

0개의 댓글