ウェブサイト検索

javascript - 入れ子の for ループのパフォーマンスを向上させる方法


こちらが私のforループです。2つの列挙型を処理し、両方をサーバーに送信して値を取得し、別のforループでその値を計算します。確実に改善できると思います。コードはこちらです:

  const paths = [];
  for await (let category of Object.values(CategoriesEnum)) {
    for await (let format of Object.values(FormatsEnum)) {
      const totalPosts = await getPagesCount(category, format);
      const totalPages = Math.ceil(totalPosts.offsetPagination.total / 12);
      for (let page = 1; page <= totalPages; page++) {
        paths.push({ params: { category: category , format: format page: page } });
      }
    }
  }
return paths;

私の主な目標は時間を短縮することですが、サーバーへのクエリの量は同じになるので、大きな違いはないことは理解しています。ありがとうございます。

回答 #1

あなたは [Promise.all][1] を使用できます。

こちらがサンプルのスニペットです。

let promises = [];
let paths = [];

Object.values(CategoriesEnum).forEach(category => {
    Object.values(FormatsEnum).forEach(format => {
        promises.push(getPagesCount(category, format))
    })
});

const totalPostCounts = await Promise.all(promises);



totalPostCounts.forEach(totalPosts => {
    const totalPages = Math.ceil(totalPosts.offsetPagination.total / 12);
    for (let page = 1; page <= totalPages; page++) {
        paths.push({ params: { category: category, format: format, page: page } });
    }
});

return paths;




[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

同じ方法を使った別のアプローチ

let promises = [];
let paths = [];


/*
Gather Api calls
*/
Object.values(CategoriesEnum).forEach(category => {
    Object.values(FormatsEnum).forEach(format => {
        promises.push(getPath(category, format))
    })
});

// wait for the call
const pathsArray = await Promise.all(promises);

// flat the array
pathsArray.forEach(pathArray => {
    paths = paths.concat(pathArray)
});


async function getPath(category, format) {
    let paths = [];

    const totalPosts = await getPagesCount(category, format);
    const totalPages = Math.ceil(totalPosts.offsetPagination.total / 12);
    for (let page = 1; page <= totalPages; page++) {
        paths.push({ params: { category: category, format: format, page: page } });
    }

    return paths;
}

回答 #2

最初に、ロジックを3つの部分に分けます:

  1. 非同期呼び出しを準備する
  2. 非同期呼び出しを並行して解決する
  3. 私のビジネスロジックを適用する
const pagesPromises = []
for  (let category of Object.values(CategoriesEnum)) {
  for  (let format of Object.values(FormatsEnum)) {
    pagesPromises.push(getPagesCount(category, format))
  }
}

const totalPostsResults = await Promise.all(pagesPromises)

const paths = [];
totalPostsResults.forEach(totalPosts => {
  const totalPages = Math.ceil(totalPosts.offsetPagination.total / 12);
  for (let page = 1; page <= totalPages; page++) {
    paths.push({ params: { category: category , format: format page: page } });
  }
})

return paths;