【问题标题】:How do I loop through async function in Nodejs如何循环通过 Nodejs 中的异步函数
【发布时间】:2018-12-18 01:14:26
【问题描述】:

这是用于 selenium WebDriver JS ax 集成的示例代码,用于测试我的网站的可访问性 -

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);
    });
  });

这里正在解析一个 URL。有人可以帮我解析多个网址吗?我希望打印所有 url 的结果作为 driver.get() 的输入。任何帮助将不胜感激!

参考 - https://github.com/dequelabs/axe-webdriverjs

【问题讨论】:

  • await 每个Promise 或使用Promise.all?

标签: javascript node.js async-await


【解决方案1】:

使用 Promise.all 并映射一个 url 数组。

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

你会得到数组finalResult中的所有结果。

【讨论】:

    【解决方案2】:

    所以我会将@CertainPerformance 的评论格式化为答案。

    最简单的方法是使用现代async/await 语法:

    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);
            });
          });
    }
    

    不要忘记将url1, url2, url3 替换为您的网址。

    附:正如@jfriend00 所述(在下面的cmets 中),我们不知道AxeBuilder 函数是否实际上返回了一个承诺。因此,在后一种情况下,它之前的await(和async)可能是不必要的。

    【讨论】:

    • 这不会等待AxeBuilder().analyze() 完成,然后再进行下一次循环迭代。
    • @jfriend00 错过了,已修复!
    • 我不知道这个库,但是 .analyze() 不太可能返回一个承诺并接受一个回调。如果它没有返回一个承诺,await 不会做任何有用的事情。
    • @jfriend00 是的,添加了后记。
    • 您仍然没有展示在迭代循环之前实际上会等待所有异步事情完成的解决方案。
    【解决方案3】:

    上述解决方案将起作用,但它会被序列化,即您将获得driver.get 承诺的结果,然后analyze 获得一个网址的结果,然后再转到下一个。也许您可以使用promise.all 并行执行所有操作。

    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);
                }
            });
        });
    }
    

    在这里,我们跟踪所有drivers,所有driver.get 承诺并行运行,一旦所有getPromises 返回(解决/拒绝),analysePromises 并行执行.

    编辑:使用异步函数的更简单的方法。上面有点复杂,你可以用异步函数来实现

    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
            });
        });
    }
    

    【讨论】:

    • 嘿 Mrinal 首先谢谢!快速的问题,如果我不希望它并行运行并序列化这个确切的代码怎么办?它运行完美,唯一的问题是如果我给它大量的 url,它会崩溃。请帮忙!
    猜你喜欢
    • 2020-04-22
    • 2019-01-17
    • 2017-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    • 2020-03-07
    相关资源
    最近更新 更多