Promise.All()

김하은·2023년 3월 6일
0

Promise.all()

일단 Promise라는 것은 API요청 등 기다렸다받는 종류의 것들이 리턴하는것을 얘기한다. (리턴을 Promise로 하는것.)

우선은 Promise.all이라는것을 적용하기 전과 뭐가다른지 그려보았다.

일단 Promise로 만들어 줘야하기에 일정시간 요청을 기다렸다 받아오는 그림으로 만들어 주기위해 setTimeout이라는 것을 사용해 각각 1초, 2초, 3초 뒤에 실행되게끔 만들어 주었다.
그리고 해단 첫부분과 마지막부분까지 얼마나 걸리는지 알기 위해 console.time()과 console.timeEnd()로 콘솔을 찍어 time에서부터timeEnd부분까지 몇초가 걸리는지 찍어보았다.

const startPromise = async () => {
        console.time("== 개별 Promise 각각 ==="); // 여기서부터
        const result1 = await new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve("성공!!");
          }, 2000); // 2초뒤에 result로 결과 받을수 있음. 아니면 await말고 .then()을 사용한다면 2초 뒤에 성공하면.then()이 실행됨.
        });
        const result2 = await new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve("성공!!");
          }, 3000);
        });
        const result3 = await new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve("성공!!");
          }, 1000);
        });
        console.timeEnd("== 개별 Promise 각각 =="); // (time ~ timeEnd)여기까지 얼마나 걸렸는지 시간찍어줌. 단, 안에 이름등 들어있는것 같아야함. 시작부분이 "== 개별 Promise 각각 =="이니 끝부분에도 "== 개별 Promise 각각 =="로
        // 총  하나씩 보내니 6초걸림
      };

위에 적혀있듯, 총 6초 정도 걸리는것으로 찍혔다.

그렇다는것은 하나씩 실행되고 그게끝나야 다음것, 그리고 그 다음것이 찍히는 등의 일이 일어난다는 것.

그러면 이번에는 Promise.all() 이라는것을 적용하면 어떻게 될까?

먼저 Promise.all이라는것을 알아보자

Promise.all() : 묶어서 한번에 보내고 하나씩 받는것.(하나기다렸다가 끝내고 다음것 보내는 방식이 아니라 한번에 보내놓고 결과만 기다리는 그런 방식!!)

해당부분을 new Promise가 아니라 Promise.all()로 묶어 사용하면된다.

전부 묶었으니 개별적으로 각각을 result1,result2, result3 등으로 묶은 과정은 더이상 필요치 않고 전부를 하나로 묶어 변수 result에 담아 찍어본다.

그리고 똑같이 시간을 재본다.

 const startPromiseAll = async () => {
        // 동시에 보내고 한번 기다릴것임.
        // await Promise.all([promise, promise, promise]); // 프로미스들을 감싸는 배열로 넣음. 한번에 다 보내고, 기다림. 먼저끝나는 순서로 담기고, 다 받아오기전까지 아래 실행 못하게 await걸기
        console.time("=== 한방  Promise.all ===");
        const result = Promise.all([
          new Promise((resolve, reject) => {
            setTimeout(() => {
              resolve("성공!!");
            }, 2000);
          }),
          new Promise((resolve, reject) => {
            setTimeout(() => {
              resolve("성공!!");
            }, 3000);
          }),
          new Promise((resolve, reject) => {
            setTimeout(() => {
              resolve("성공!!");
            }, 1000);
          }),
        ]);
        console.log(result); // 배열안에 각각의 결과가 담긴다.
        console.timeEnd("=== 한방  Promise.all ===");
        //  한번에 보내고 먼저끝나는 순서로 받아오기때문에 총 3초 걸림
      };

이렇게 해서 시간을 재보면 한번에 보내기에 1초에 하나실행, 2초에 하나실행, 마지막 3초에 하나가 실행되며 총 3초가 걸린다는 것을 볼 수 있다.

이번에는 이미지를 배열에 담아 3개를 보내본다.

Promisse.all을 사용하지 않을때

 1. Promise.all 안썼을때 - 하나보내고 기다리고, 하나보내고 기다리고..
 const resultFile0 = await uploadFile({ variables: { file: files[0] } }); // 파일 업로드하여 그 결과를 resultFile에  담음(스토리지로 보냄)
 const url0 = resultFile0.data?.uploadFile.url; // 그 결과에서 url을 받아옴.(스토리지url)
 const resultFile1 = await uploadFile({ variables: { file: files[1] } }); // 파일 업로드하여 그 결과를 resultFile에  담음(스토리지로 보냄)
 const url1 = resultFile1.data?.uploadFile.url;
 const resultFile2 = await uploadFile({ variables: { file: files[2] } }); // 파일 업로드하여 그 결과를 resultFile에  담음(스토리지로 보냄)
   const url2 = resultFile2.data?.uploadFile.url;
 const resultUrls = [url0, url1, url2]; // 각각의 url을 뽑아서 배열에 들어가는것은 각각의 url [dog1.jpg,dog2.jpg,dog3.jpg]

엄청길어진다. 게다가 반복되는 부분도 있다. 이부분을 Promise.all() 을 사용해 1차적으로 줄여준다면

2. Promise.all 썼을때 -- 한번에보내고 기다림
 const results = await Promise.all([
  uploadFile({ variables: { file: files[0] } }),
  uploadFile({ variables: { file: files[1] } }),
  uploadFile({ variables: { file: files[2] } }),
    ]);
   console.log(results); // 얘는  [resultFile0,resultFile1,resultFile2] . 결과가 url이 아님.map을 사용해 해당의 url을 뽑기
 const resultUrls = results.map((el) => (el ? el.data?.uploadFile.url : "")); // el이 없으면 빈 문자열로.  [dog1.jpg,dog2.jpg,dog3.jpg]
  이때의 results로 받아오는 것은 각각 업로드한 파일 하나하나고, 이들을 이용해 map으로 각각의 data의 url을 뽑아와야 배열에 각각의 사진 url이 담긴다.
  
  
  
  그런데 보니까 valrialbes에 file:files[0] 해서 각각의 인덱스가 들어가는것을 볼 수 있다. 
  그렇다면 애초에 files를 map으로 돌려 el그러니까 업로드 파일이 있을경우에 업로드 파일을 실행하도록 만든다.
  
  그리고 동일하게 그 결과를 다시 map으로뿌려 url만 받아 resultUrls에 담고 해당부분을 활용해 뮤테이션을 날린다.
  
  
  >```
const result = await 나의함수({
      variables: {
        createBoardInput: {
          writer: "유리",
          title: "안녕하세요",
          contents: "반갑습니다",
          password: "1234",
          images: resultUrls, // [url0,url1,url2]
        },
      },
    });
    console.log(result);
;
  };

-- 이미지를 제외한 해당 내용들은 하드코딩 적용.

이런식으로 여러개를 한번에 Promise.all을 이용해 적용했다고 한다면, 뮤테이션도 바뀌어야한다. 여러개를 보내니 배열 형태로, 그러나 원본은 건들이지 않는것이 좋으므로 스프레드 연산자를 사용해 복사하여 state에 담아 이용하도록한다.

0개의 댓글