for 循环中的 WebDriver 链接仅迭代循环而不执行回调

WebDriver chaining within a for loop only iterates the loop without executing the callback

我正在编写 Appium (v1.7.1) iOS 自动化测试,我正在链接一个 webdriver 会话并尝试循环遍历元素以获取数据。

setFilterOptions: function (driver, loc) {
    var chain = driver;                  //I am assigning the driver to chain
    chain = chain
         .getFilterElementListCount()    //This gives me back the count for elements
         .then((count) => {
            console.log("Number of Filters - ",count);  

            for(var i=1; i<=count; i++) {
              ((i) => {
                console.log("Value of i - ", i);
                //This gives me the label for each Cell->StaticText
                chain = chain
                      .getElAttribute('label',util.format('//XCUIElementTypeCell[%d]/XCUIElementTypeStaticText[1]', i), 'xpath')                           
                      .then((filterTitle, i) => {
                            console.log("Filter Title - ", filterTitle);
                            console.log("I value - ", i);
                      });
              })(i);
            }
         });
  return chain;
},    

The Console o/p i am getting is - 
Number of Filters -  3
Value of i -  1
Value of i -  2
Value of i -  3

循环迭代但不执行 for 循环内的链。有没有办法让链在返回之前完成所有回调执行。

您的目标是 return 一个将在 所有 循环中执行的工作完成后解决的承诺。但是,那不是你在做什么。你的问题是你有这个:

  chain = chain.//
                // Bunch of asynchronous operations, some of which assign 
                // to the variable `chain`.
                //
  return chain;

为了让您的代码正常工作,异步操作必须在 return 语句执行之前分配给 chain 。但这不是异步操作的工作方式。当您调用任何异步方法时,您只是在安排异步操作以供将来执行。它会在未来的某个时间点执行,但绝对不会立即。在您拥有的代码中,您安排了一个异步操作,并立即 return chain您 return chain 的值不能 是在您的循环中设置的值。 您的循环没有尚未执行。

您应该执行如下操作。重要的是在循环和 return 中创建一个操作链,从您传递给 .then 的函数链 以便最顶层的承诺解析为您在循环中创建的链。这样,您 return 从您的方法 中得到的承诺将 必须等待所有内部操作完成才能被解析。

setFilterOptions: function (driver, loc) {
    return driver
         .getFilterElementListCount()    //This gives me back the count for elements
         .then((count) => {
            var chain = Promise.resolve();
            console.log("Number of Filters - ",count);  

            for(var i=1; i<=count; i++) {
              ((i) => {
                console.log("Value of i - ", i);
                //This gives me the label for each Cell->StaticText
                chain = chain
                      .getElAttribute('label',util.format('//XCUIElementTypeCell[%d]/XCUIElementTypeStaticText[1]', i), 'xpath')                           
                      .then((filterTitle, i) => {
                            console.log("Filter Title - ", filterTitle);
                            console.log("I value - ", i);
                      });
              })(i);
            }

            // Return your promise!                
            return chain;
         });
},    

另请注意,如果您在循环中使用 let i 而不是 var i,您可以摆脱循环中立即调用的箭头函数,它似乎只存在于确保循环内的闭包获得 i 的顺序值(而不是所有执行都使用 i 的最后一个值)。