【问题标题】:Parallel HTTP requests in batches with async for loop for each request批量并行 HTTP 请求,每个请求都有 async for 循环
【发布时间】:2020-09-15 08:48:09
【问题描述】:

我正在尝试使用数组中的一堆关键字对 API 批量运行并行请求。 Article by Denis Fatkhudinov.

我遇到的问题是,对于每个关键字,我需要使用不同的 page 参数再次运行请求,其次数与 pages 变量中的数字一样多。

我不断收到Cannot read property 'then' of undefined 以返回chainNext 函数。

单独批量并行请求,没有for循环,效果很好,我正在努力将for循环合并到进程中。

// Parallel requests in batches
async function runBatches() {
  // The keywords to request with 
  const keywords = ['many keyword strings here...'];
  // Set max concurrent requests
  const concurrent = 5;
  // Clone keywords array
  const keywordsClone = keywords.slice()
  // Array for future resolved promises for each batch
  const promises = new Array(concurrent).fill(Promise.resolve());
  // Async for loop
  const asyncForEach = async (pages, callback) => {
    for (let page = 1; page <= pages; page++) {
      await callback(page);
    }
  };
  // Number of pages to loop for
  const pages = 2;

  // Recursively run batches
  const chainNext = (pro) => {
    // Runs itself as long as there are entries left on the array
    if (keywordsClone.length) {
      // Store the first entry and conviently also remove it from the array
      const keyword = keywordsClone.shift();
      // Run 'the promise to be' request
      return pro.then(async () => {
        // ---> Here was my problem, I am declaring the constant before running the for loop
        const promiseOperation = await asyncForEach(pages, async (page) => {
          await request(keyword, page)
        });
        // ---> The recursive invocation should also be inside the for loop
        return chainNext(promiseOperation);
      });
    }

    return pro;
  }

  return await Promise.all(promises.map(chainNext));
}

// HTTP request
async function request(keyword, page) { 
  try {
    // request API 
    const res = await apiservice(keyword, page);
    // Send data to an outer async function to process the data
    await append(res.data);
  } catch (error) {
    throw new Error(error) 
  }
}


runBatches()

【问题讨论】:

    标签: javascript node.js async-await es6-promise


    【解决方案1】:

    问题只是 pro 是未定义的,因为你还没有初始化它。

    你基本上执行了这段代码:

    Promise.all(new Array(concurrent).fill(Promise.resolve().map(pro => {
      // pro is undefined here because the Promise.resolve had no parameter
      return pro.then(async () => {})
    }));
    

    我不完全确定您背后的想法,但这是您在更精简版本中的问题。

    【讨论】:

    • 一开始应该是未定义的,我从itnext.io/…获取了批处理代码,那里也显示未定义,但随后它们被填充并且一切正常
    【解决方案2】:

    我通过在 for 循环中移动实际请求 promiseOperation 并在那里返回递归函数来让它工作

    // Recursively run batches
    const chainNext = async (pro) => {
      if (keywordsClone.length) {
        const keyword = keywordsClone.shift()
        return pro.then(async () => {
          await asyncForEach(pages, (page) => {
            const promiseOperation = request(keyword, page)
            return chainNext(promiseOperation)
          })
        })
      }
      return pro
    }
    

    批量并行请求的功劳归https://itnext.io/node-js-handling-asynchronous-operations-in-parallel-69679dfae3fc

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-16
      • 1970-01-01
      • 2019-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多