javascript: 올바른 방법으로 여러 API 호출 만들기

8470 단어 nodejavascript
최근에 PR을 검토하는 동안 함수가 병렬로 호출할 수 있는 여러 호출을 하나씩 만들고 있음을 깨달았습니다. 이 게시물에서 나는 두 개의 서로 다른 코드 조각(모의 포함)과 두 코드가 독립적으로 진행되는 방식을 보여주는 그래프를 공유하고 싶습니다.

시작하자!!

전체 사용자 목록을 얻기 위해 API를 여러 번 호출해야 하는 시나리오가 있다고 가정하고, 시스템에 사용자가 500 있지만 API가 최대값pageSize으로 제한되어 있다고 가정합니다. ) .

위의 가정에서 전체 사용자 목록을 가져오려면 100 호출을 해야 합니다.

모의/가짜 API 엔드포인트를 생성해 보겠습니다.

function fakeApiCall(currentPage) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        data: {
          currentPage,
          total: 100000,
        },
      });
    }, 1000);
  });
}


이것은 10 이후에 해결될 promise를 반환합니다.

One more use case: Let's suppose we get a requirement to get the list of all users to process something beforehand (it could be anything, for eg: may be we just want to show the list of active users when admin lands on Admin Panel, to do that we will have to get all the users and then filter out the in-active one).



1. 이 문제를 해결하는 첫 번째 방법:




async function oneByOneCall() {
  ...
  let currentPage = 1;

  while (currentPage <= 5) {
    let { data } = await fakeApiCall(currentPage);
    result = [...result, data];
    currentPage++;
  }
  ...
  // Do something with final result
}


async/await은 약속을 처리하는 동안 많은 편안함을 제공하며 코드를 작성하고 이해하는 것도 매우 쉽습니다.

그러나 코드를 한 번 더 살펴보겠습니다.

그래서 여기서 무슨 일이 일어나고 있습니다.

let { data } = await fakeApiCall(currentPage);


여기에서 우리는 API를 호출하고 결과가 돌아올 때까지 기다린 다음 해당 결과를 처리한 다음 while 루프를 계속 진행한다고 말합니다. 결과가 돌아올 때까지 기다리는 동안 이 시점에서 실행이 중지됩니다.

뭐?? 그것은 우리가 원하는 것이 아니라 병렬로 처리하기를 원했습니다. 오른쪽?

NOTE: There will be scenarios where you will have wait, could be because you are making calls to multiple APIs and you want to decide or send some data from previous response, but thats not something we are tackling here



2. 이 문제를 해결하는 두 번째 방법:




async function parallelCall() {
  ...
  let start_time = new Date().getTime();
  let promises = [];
  let result = [];

  let currentPage = 1;

  while (currentPage <= 5) {
    promises.push(fakeApiCall(currentPage));
    currentPage++;
  }

  const data = await Promise.all(promises);
  data.forEach(({ data }) => {
    result = [...result, data];
  });

  ...
  // Do something with final result
}


그래서 여기서 우리는 약속 배열을 갖게 될 것이라고 말하고 있습니다.

  let promises = [];


그리고 루프에서 우리는 1000ms에서 반환된 각 promise를 푸시하고 지금 당장 결과를 기다리지 않을 것입니다.

    promises.push(fakeApiCall(currentPage));


루프 또는 모든 약속 수집을 마치면 각 약속이 한 번만 완료될 때까지 기다립니다.

  const data = await Promise.all(promises);


다음은 실행 순서와 비교를 더 잘 나타내는 그래프입니다.

1. API 호출을 하나씩 만들고 모든 호출 후 응답을 기다립니다.





2. API 호출을 병렬로 수행하고 배열의 모든 약속을 수집하고 마지막에만 대기합니다.





마지막으로 여기에서 거의 4초(4000ms)가 증가하고 있음을 알 수 있습니다. 그것은 엄청난 이득입니다. 따라서 두 번째 옵션은 첫 번째 옵션보다 훨씬 낫습니다.

이 게시물에서 사용된 코드는 사용할 수 있습니다here.

-- 감사합니다, 라비

좋은 웹페이지 즐겨찾기