等待在reduce()函数中完成异步函数

时间:2018-04-22 11:49:55

标签: javascript asynchronous es6-promise reduce npm-request

我有一个功能,其中包括以下内容:

const newThreads = newItems.reduce( (acc, item) => {
  request(item.href, function(error2, response2, html2){

    if(!error2) {

      const thread = cheerio.load(html2)
      const today = thread('div#ignmsgbttns1').parent().parent().find("b:contains('Today')")

      if(today.text()) {
        acc.push(item)
      }

    }
  })
  return acc
}, [])

console.log(newThreads)

当然,由于异步内容,日志返回一个空数组 (request)在reduce循环中执行。

所以我想做的是:

const newThreads = await newItems.reduce( etc...

等待requests循环中的reduce完成。

但我不知道如何正确地做到这一点。

所以我知道我必须使用asyncawaitpromises,但不知道该怎么做。

我认为reduce callback也必须是async,但在这一点上绝对不确定。

request方法来自npm request package,它们也提供了一些packages来使用承诺,但说实话,我不知道如何应用link {1}}。

我很确定在某个地方已经有类似的问题,但无法找到它。

非常感谢任何帮助。

ps:对于那些想知道cheerio是什么的人,这里是async-request package

应用答案后的最终代码

我必须使用enter image description here

reduce

1 个答案:

答案 0 :(得分:0)

为了完成这项工作,您需要Promise returning version

const newThreads = newItems.reduce(async (acc, item) => { // note async
  const current = await acc; // unwrap the previous Promise
  try {
    const html2 = await request(item.href); // unwrap request Promise
    const thread = cheerio.load(html2);
    const today = thread('div#ignmsgbttns1')
      .parent()
      .parent()
      .find("b:contains('Today')");

    if (today.text()) current.push(item);
  } catch (error2) {
    // do whatever
  }
  return current;
}, []);

newThreads变量将是通过条件检查的项目数组的承诺。