Koras02
Koras02코딩웹
Koras02
전체 방문자
오늘
어제
  • 분류 전체보기 (299)
    • 백엔드 (59)
      • nestjs (2)
      • Ruby (3)
      • PostgresQL (11)
      • MySQL (5)
      • Haskell (7)
      • Koa (3)
      • Java (3)
      • Python (5)
      • Rust (5)
      • MongoDB (2)
      • PHP (3)
      • Spring Boot (1)
      • redis (5)
      • deno (2)
    • 웹서버 (3)
      • nginx (1)
      • Apache (2)
      • Google Web Server (0)
    • 모바일개발 (5)
      • Figma (0)
      • React Native (2)
      • swift (0)
      • Flutter (3)
      • Kotlin (0)
    • 프론트 엔드 (158)
      • HTML (34)
      • CSS (7)
      • Javascript (35)
      • Angular (0)
      • Typescript (2)
      • React (58)
      • Vue (2)
      • GIT (6)
      • GraphQL (1)
      • Doker (4)
      • Go (8)
      • svelte (1)
      • gatsby (0)
    • etc. (47)
      • Notion (0)
      • TIL (24)
      • Algorithm (17)
      • Algorithm 개념 정리 (2)
      • Wiki (3)
      • Official document (1)
    • 웹개념 (12)
    • 변수정리 (1)
    • VSCode (2)
    • 포트폴리오 분석 (2)
      • React (2)
    • os (5)
      • 윈도우 (4)
      • Mac (0)
      • 가상머신 (0)
      • linux (1)
    • 응용프로그램언어 (2)
      • C (2)
      • C++ (0)
      • C# (0)
    • 블로그 운영관련 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
글쓰기

공지사항

  • [공지사항] 개발 이슈나 공식문서 업데이트 업로드 예정입니⋯

인기 글

태그

  • 문자열
  • Haskell
  • PostgreSQL
  • html
  • koa
  • 알고리즘
  • Rust
  • React
  • redis
  • html5
  • Java
  • mysql
  • Til
  • 데이터 타입
  • CSS
  • go
  • javascript
  • 하스켈
  • 프로그래머스
  • Flutter

티스토리

최근 댓글

최근 글

250x250
hELLO · Designed By 정상우.
Koras02

Koras02코딩웹

[Javascript] Promise.all 이란?
프론트 엔드/Javascript

[Javascript] Promise.all 이란?

2022. 2. 2. 05:20
728x90

Promise자체의 뜻은 약속이라는 뜻입니다. 여기서 all이라는 것이 붙으면 어떤 뜻일까요?

 

Promise.all

Promise.all 이라는 뜻은 모든 프라미스가 이행될 때까지 기다리다 그 결과 값을 담은 배열을 반환하는 매서드입니다.


Promise란?

위 그림은 동기와 비동기에 대한 설명을 담은 그림입니다. 데이터를 요청하고 응답이 들어올 때까지 다른 

task들을 처리할 수 있도록 하는 것이 바로 비동기입니다.

 

prmise는 위의 비유와 같이 진동벨과 같은 역할을 한다고 생각할 수 있습니다.

사장님과 손님의 진동벨을 연결하는 것과 같이, 프로미스(Promise)는 '제작 코드'와 '소비코드'를 연결해주는 

특별한 자바스크립트 객체입니다.

 

'제작 코드'와 '소비 코드'에 대한 설명은 아래에서 코드를 보면서 설명해 보겠습니다.

let promise = new Promise(function(resolve, reject) {
   setTimeout(() => resolve("done!"), 1000);
   // executor, 제작 코드
});

promise.then(
   result => alert(result);
   error => alert(error);
   // 소비 코드
)

위코드의 결과는 1초 후에 'done!'이 출력되는 코드 입니다. 그 이유에 대해서는 천천히 알아보도록 하겠습니다.

 

executor의 인수 resolve와 reject는 자바스크립트가 자체적으로 제공하는 콜백 함수 입니다. 

개발자는 resolve와 reject를 신경 쓰지 않고 executor 안의 코드만 작성하면 됩니다.

 

대신에 executor에선 결과를 즉신 얻든, 늦게 얻든 간에 상관없이 상황에 따라 인수로 넘겨준 콜백 중 하나를 

반드시 호출해야 합니다.

 

  • resolve(value) - 일이 성공적으로 끝난 경우, 그 결과를 나타내는 value와 함께 호출 
  • reject(error) - 에러 발생 시 에러 객체를 나타내는 error와 함께 호출

result는 promise객체의 내부 property로 처음엔 undefined였습니다. resolve(value)가 호출되면

value로, reject(error)가 호출되면 error로 변합니다.

 

위 코드의 결과가 'done'이 실행되는 이유는 resolve("done")에 의해 result의 값이 resolve함수의 인수인 

"done"으로 변했기 때문입니다.

 

위에서 언급했듯 카페 사장님과 손님의 관계를 다시 생각해보면, 제작코드(executor)는 사장님입니다.

그 사장님이 완성한 커피는 result가 되고, 그리고 그 커피를 받은 손님은 소비코드가 되는 것 입니다.

 

그리고 이 과정에서 커피의 완성을 알려주는 진동벨이 바로 Promise가 되는 것 입니다.

 

Promise.all은 언제 사용하는가?

여러개의 프로미스를 모두 리졸브가 된 후에는 , 다음 로직을 실행해야하는 경우에 사용합니다.

복수의 URL에 request를 보내고, 모든 요청의 응답이 올때 화면을 랜더 해야하는 상황이 그 예시입니다.

 

요청에 필요한 정보를 배열로 저장한 뒤, 그후 해당 정보를 프로미스로 매핑하여 Promise.all()에 입력하는 

방법이 자주 쓰입니다.

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

Promise.all(
  [promise1, promise2, promise3, promise4]).then((values) => {
  console.log(values);
});
//output: Array [3, 42, "foo1","foo2"]

처리하고자 하는 프로미스들을 배열로 담아서 Promise.all에 인자로 전달하면 배열에 있는 모든 프로미스들이 

거의 동시에 트리거 됩니다. 그래서 promise3, promise4의 결과는 각각 1초가 걸리지만 동시에 트리거 

 

되기 떄문에 2초후에 결과가 나오는 것이 아닌 1초 후에 결과가 나와야 하는 겁니다.

promise.all()을 사용할 때 주의해야할 점은 배열 내 요소 중 어느 하나라도 거부하면 즉시 거부한다는 겁니다.

let p1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('하나'), 1000);
});
let p2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('둘'), 2000);
});
let p3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('셋'), 3000);
});
let p4 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('넷'), 4000);
});
let p5 = new Promise((resolve, reject) => {
  reject(new Error('거부'));
});


// .catch 사용:
Promise.all([p1, p2, p3, p4, p5])
.then(values => {
  console.log(values);
})
.catch(error => {
  console.log(error.message)
});

위 코드에서 p5가 Error를 반환하기 때문에 p1,p2,p3,p4의 결과는 출력되지 못하게 됩니다.

만약 p1,p2,p3,p4의 결과를 보고 싶다면 발생할 수 있는 거부를 사전에 처리하면 됩니다.

let p1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('p1_지연_이행'), 1000);
})

let p2 = new Promise((resolve, reject) => {
  reject(new Error('p2 즉시 거부'));
})

Promise.all([
   p1.catch(error => { return error }),
   p2.catch(error => { return error }),
]).then(values => {
   console.log(values[0]); // "p1_지연_이행"
   console.log(values[1]); // "Error: p2_즉시 거부"
})

위 코드를 해석하면 p2에서 발생하는 거부를 .catch()를 이용해 미리 처리 하엿기 때문에 결과 배열의 p1의 결과와

p2의 error내용이 담기게 된 것입니다.

 

참고 자료

 

Promise.all(), Promise.race(), Promise.finally()

promise의 다양한 메소드들에 대해 알아봅시다😎

velog.io

 

[메모] Promise.all

여러개의 프로미스가 모두 리졸브 된 후, 다음 로직을 실행해야한는 경우에 사용

velog.io

 

'프론트 엔드 > Javascript' 카테고리의 다른 글

[Javascript] 디바운싱과 쓰로틀링  (0) 2022.02.02
[Javascript] 자바스크립트 엔진, V8  (0) 2022.01.30
[Javascript] Event Loop  (0) 2022.01.24
    '프론트 엔드/Javascript' 카테고리의 다른 글
    • [Javascript] Object, key, values, entries, assign
    • [Javascript] 디바운싱과 쓰로틀링
    • [Javascript] 자바스크립트 엔진, V8
    • [Javascript] Event Loop
    Koras02
    Koras02
    현재 사용중인 언어 - next-js,react,vue, typescript

    티스토리툴바