Javascript 如何在Nodejs中循环异步函数

Javascript 如何在Nodejs中循环异步函数,javascript,node.js,async-await,Javascript,Node.js,Async Await,下面是一个示例代码,我正在使用它进行selenium WebDriver JS axe集成,以测试我的网站的可访问性- var AxeBuilder = require('axe-webdriverjs'); var WebDriver = require('selenium-webdriver'); var driver = new WebDriver.Builder() .forBrowser('firefox') .build(); driver .get('https:/

下面是一个示例代码,我正在使用它进行selenium WebDriver JS axe集成,以测试我的网站的可访问性-

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吗?我希望打印所有URL的结果,作为driver.get()的输入。任何帮助都将不胜感激


参考-

因此我将@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);
        });
      });
}
不要忘记用URL替换
url1、url2、url3


另外,正如@jfriend00所述(在下面的评论中),我们不知道AxeBuilder函数是否实际返回承诺。因此,在后一种情况下,
等待
(和
异步
)可能是不必要的

所以我将@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);
        });
      });
}
不要忘记用URL替换
url1、url2、url3


另外,正如@jfriend00所述(在下面的评论中),我们不知道AxeBuilder函数是否实际返回承诺。因此,在后一种情况下,
等待
(和
异步
)可能是不必要的

上述解决方案将起作用,但它将被序列化,即您将获得
驱动程序的结果。获取
承诺,然后
分析
一个url的结果,然后再移动到下一个url。也许你可以使用
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);
            }
        });
    });
}

上述解决方案可行,但会序列化,即您将获得
驱动程序的结果。获取
承诺,然后
分析
一个url的结果,然后再移动到下一个url。也许你可以使用
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);
            }
        });
    });
}

使用Promise.all并映射url数组

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

您将在数组中获得所有结果
finalResult

使用Promise.all并映射url数组

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

您将在数组中获得所有结果
finalResult

等待
每个
承诺
或使用
承诺。所有
等待
每个
承诺
或使用
承诺。所有
?这不会等待
AxeBuilder().analyze()
在进入循环的下一次迭代之前完成。@jfriend00错过了,修复了!我不知道这个库,但是.analyze()不太可能返回承诺并接受回调。如果它没有返回承诺,wait将不会做任何有用的事情。@jfriend00 Yep,添加了一个postscriptum。您仍然没有显示一个解决方案,该解决方案实际上会在迭代循环之前等待所有异步操作完成。这不会等待
AxeBuilder().analyze()
在进入循环的下一次迭代之前完成。@jfriend00错过了,修复了!我不知道这个库,但是.analyze()不太可能返回承诺并接受回调。如果它没有返回承诺,wait将不会做任何有用的事情。@jfriend00是的,添加了一个postscriptum。您仍然没有显示一个解决方案,该解决方案实际上会在迭代循环之前等待所有异步操作完成。嘿,谢谢!快速提问,如果我不想让它并行运行并序列化这个确切的代码,该怎么办?它运行完美唯一的问题是,如果我给它大量的URL,它会崩溃。请帮忙!嘿,谢谢!快速提问,如果我不想让它并行运行并序列化这个确切的代码,该怎么办?它运行完美唯一的问题是,如果我给它大量的URL,它会崩溃。请帮忙!