sulaxe
sulaxe

Reputation: 1

How do I loop through async function in Nodejs

Here is a sample code which am using for selenium WebDriver JS axe integration to test my website for accessibility -

var AxeBuilder = require('axe-webdriverjs');
var WebDriver = require('selenium-webdriver');

var driver = new WebDriver.Builder()
  .forBrowser('firefox')
  .build();

driver
  .get('https://dequeuniversity.com/demo/mars/')
  .then(function() {
    AxeBuilder(driver).analyze(function(err, results) {
      if (err) {
        // Handle error somehow
      }
      console.log(results);
    });
  });

There is one URL that is being parsed here. Can someone help me with how I can parse multiple urls? I would want the print the results of all the urls being given as input to driver.get(). Any help would be appreciated !

Reference - https://github.com/dequelabs/axe-webdriverjs

Upvotes: 0

Views: 502

Answers (3)

Mrinal
Mrinal

Reputation: 108

the above solution will work, but it will be serialized i.e. you will get the result of the driver.get promise and then analyze the result of one url before moving to the next. maybe you could use promise.all to do it all in parallel. Something on the lines of

function executeGetPromises() {
    var getPromises = [];
    var drivers = [];
    for (const url of [url1, url2, url3]) {
        var driver = new WebDriver.Builder().forBrowser('firefox').build();
        getPromises.push(driver.get(url));
        drivers.push(driver);
    }

    var analysePromises = [];
    int index = 0;
    Promise.all(getPromises.map(p => p.catch(e => e)))
        .then(results => {
            for (int i=0; i< results.length; i++) {
                var result = results[i];
                if (!(result instanceof Error)) {
                    analysePromises.push(AxeBuilder(drivers[i]).analyze);
                }
            }
        executeAnalysePromises(analysePromises);
    });
}

function executeAnalysePromises (analysePromises) {
    Promise.all(analysePromises.map(p => p.catch(e => e)))
    .then(results => {
        results.forEach(result => {
            if (!(result instanceof Error)) {
                console.log(result);
            }
        });
    });
}

here we are keeping a track of all the drivers, and all the driver.get promises are run in parallel and once all the getPromises return (either resolved/rejected), the analysePromises get executed in parallel.

EDIT: A more simpler approach using async functions. The above is a bit complicated, you can achieve the same using async functions

async function executeTask (driver, url) {
    try{
        await driver.get(url);
        let result = await AxeBuilder(driver).analyze();
        return Promise.resolve(result);
    } 
    catch(err) {
        return Promise.reject(err);
    }
}

function iterateThroughUrls(urls) {
    urls.forEach(url => {
        var driver = new WebDriver.Builder().forBrowser('firefox').build();
        executeTask(driver, url).then(result => {
            console.log(result);
        }).catch(err => {
            //handle errors
        });
    });
}

Upvotes: 1

Nurbol Alpysbayev
Nurbol Alpysbayev

Reputation: 21851

So I'll format the @CertainPerformance's comment as an answer.

The simplest approach is using the modern async/await syntax:

for (const url of [url1, url2, url3]) {
    await driver
      .get(url)
      .then(async function() {
        await AxeBuilder(driver).analyze(function(err, results) {
          if (err) {
            // Handle error somehow
          }
          console.log(results);
        });
      });
}

Do not forget to replace url1, url2, url3 with your urls.

P.S. as @jfriend00 stated (in comments below), we don't know if AxeBuilder function is actually returns a promise or not. So the await before it (and async) may be unnecessary in the latter case.

Upvotes: 1

Akhi Akl
Akhi Akl

Reputation: 3931

Use Promise.all and map a url array.

const urlArray = [url1,url2,url3,...];
const finalResult = await Promise.all(urlArray.map(async url=>{
   return await driver.get(url);
}))

you will get all the result in the array finalResult.

Upvotes: 1

Related Questions