I have a fuction which includes the following:
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)
Of course the log returns an empty array, because of the async stuff
(request
) executed in the reduce
loop.
So what I would like to do is:
const newThreads = await newItems.reduce( etc...
And wait for the requests
in the reduce
loop to be done.
But I don't get my head around how to do it properly.
So I know I have to use async
, await
or promises
, but don't know how to do it.
I think the reduce callback
also has to be async
but absolutely not sure on this point.
The request
method comes from the npm request package , they also provide some packages to use promises, but to be honest, I don't know how to apply it with reduce
.
I'm pretty sure there is already a similar question somewhere but couldn't find it.
Any help would be greatly appreciated.
ps: for those wondering what cheerio is, here the link.
Final code after applying answer
I had to use the async-request package
const newThreads = newItems.reduce(async (acc, item) => {
const current = await acc;
const html2 = await requestAsync(item.href);
const thread = cheerio.load(html2.body);
const today = thread('div#ignmsgbttns1')
.parent()
.parent()
.find("b:contains('Today')");
if (today.text()) current.push(item);
return current;
}, []);
newThreads.then((res) => {
//..doing stuff with res
})
In order to make this work you'll need the 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;
}, []);
The newThreads
variable will be a Promise of an array of items that passed the conditional check.