Calling async function multiple times

2024/2/27 8:38:04

So I have a method, which I want to call multiple times in a loop. This is the function:

function PageSpeedCall(callback) {var pagespeedCall = `https://www.googleapis.com/pagespeedonline/v4/runPagespeed?url=https://${websites[0]}&strategy=mobile&key=${keys.pageSpeed}`;// second callvar results = '';https.get(pagespeedCall, resource => {resource.setEncoding('utf8');resource.on('data', data => {results += data;});resource.on('end', () => {callback(null, results);});resource.on('error', err => {callback(err);});});// callback(null, );
}

As you see this is an async function that calls the PageSpeed API. It then gets the response thanks to the callback and renders it in the view. Now how do I get this to be work in a for/while loop? For example

function PageSpeedCall(websites, i, callback) {var pagespeedCall = `https://www.googleapis.com/pagespeedonline/v4/runPagespeed?url=https://${websites[i]}&strategy=mobile&key=${keys.pageSpeed}`;// second callvar results = '';https.get(pagespeedCall, resource => {resource.setEncoding('utf8');resource.on('data', data => {results += data;});resource.on('end', () => {callback(null, results);});resource.on('error', err => {callback(err);});});// callback(null, );
}var websites = ['google.com','facebook.com','stackoverflow.com'];
for (let i = 0; i < websites.length; i++) {PageSpeedCall(websites, i);
}

I want to get a raport for each of these sites. The length of the array will change depending on what the user does.

I am using async.parallel to call the functions like this:

let freeReportCalls = [PageSpeedCall, MozCall, AlexaCall];async.parallel(freeReportCalls, (err, results) => {if (err) {console.log(err);} else {res.render('reports/report', {title: 'Report',// bw: JSON.parse(results[0]),ps: JSON.parse(results[0]),moz: JSON.parse(results[1]),// pst: results[0],// mozt: results[1],// bw: results[1],al: JSON.parse(results[2]),user: req.user,});}
});

I tried to use promise chaining, but for some reason I cannot put it together in my head. This is my attempt.

return Promise.all([PageSpeedCall,MozCall,AlexaCall]).then(([ps,mz,al]) => {if (awaiting != null)var areAwaiting = true;res.render('admin/', {title: 'Report',// bw: JSON.parse(results[0]),ps: JSON.parse(results[0]),moz: JSON.parse(results[1]),// pst: results[0],// mozt: results[1],// bw: results[1],al: JSON.parse(results[2]),user: req.user,});
}).catch(e => {console.error(e)
});

I tried doing this:

return Promise.all([for(let i = 0;i < websites.length;i++){PageSpeedCall(websites, i)}, MozCall, AlexaCall]).
then(([ps, mz, al]) => {if (awaiting != null)var areAwaiting = true;res.render('admin/', {title: 'Report',// bw: JSON.parse(results[0]),ps: JSON.parse(results[0]),moz: JSON.parse(results[1]),// pst: results[0],// mozt: results[1],// bw: results[1],al: JSON.parse(results[2]),user: req.user,});
}).catch(e => {console.error(e)
});

But node just said it's stupid.

And this would work if I didn't want to pass the websites and the iterator into the functions. Any idea how to solve this?

To recap. So far the functions work for single websites. I'd like them to work for an array of websites.

I'm basically not sure how to call them, and how to return the responses.

Answer

It's much easier if you use fetch and async/await

const fetch = require('node-fetch');async function PageSpeedCall(website) {const pagespeedCall = `https://www.googleapis.com/pagespeedonline/v4/runPagespeed?url=https://${website}&strategy=mobile&key=${keys.pageSpeed}`;const result = await fetch(pagespeeddCall);return await result.json();
}async function callAllSites (websites) {const results = [];for (const website of websites) {results.push(await PageSpeedCall(website));}return results;
}callAllSites(['google.com','facebook.com','stackoverflow.com']).then(results => console.log(results)).error(error => console.error(error));

Which is better with a Promise.all

async function callAllSites (websites) {return await Promise.all(websites.map(website => PageSpeedCall(website));
}
http://en.ppmy.cn/q/42166.html

Related Q&A

Simple message passing between background.js to contentScript.js

Im trying to apply the following flow : binding for keys in the background.js , when pressing them : Sending message from background.js -> contentScript.js Sending response from contentScript.js -&g…

Having trouble calculating mandelbrot set iterations

So I read up this article: http://www.wikihow.com/Plot-the-Mandelbrot-Set-By-Hand But Im stuck at step 7. Im drawing the set in javascript canvas.All I need is basicly the C value I guess.for (var y = …

Antd Select Component mode multiple, checkbox styling

Using antd NPM package, select component, in multiple mode, by default checkbox shows up at right. I want to align it to left and style it like tick mark in the box followed by a label. Also, need sear…

Jquery - waiting for user input

im trying to make a popup that comes up to confirm a users action (deleting a row in a table, for example..). aiming at making the popup entirely HTML and Javascript. What i cant get my head around is …

Read email headers in Outlook Web Access (OWA)

I am developing a outlook Web App (Office 365 Developer). Regarding that, is there a way to read the headers of the selected mail which lays on inbox?. I am using Exchange server 2013. I would like to…

I am trying to send text- messages on WhatsApp with javascript?

I am trying to send text messages on whatsapp web version on chrome. (www.web.whatsapp.com)This is the code:document.getElementsByClassName("input")[1].innerHTML="This message was writte…

Ajax functions like .load() strip out comments from the HTML. How can I keep the comments?

For example, $(#some-div).load(http://foo.bar #content) will retrieve #content from http://foo.bar but with all HTML <!--comments--> stripped.How can I retrieve the contents of #content including…

Typescript: object assignment with excess keys seems broken

First variant: I pass object data from the const. Second variant: I pass data directly in the function. Why do I have an error only in the second variant? First: const a = {name: 123,age: 30,excess: […

angularjs Click button to show next / previous div

I have a stack of Divs created with ng-repeat. PlunkerQuick Image:Is it possible to create this stack of div work like a slider? Like: if I press Next button Top div will slide away and 2nd top will s…

Chrome extension to parse google search results

Im trying to make a little extension that checks the google search results for wikipedia articles, and adds a little extra link afterwards. But am having a little trouble parsing the search results. It…