代码之家  ›  专栏  ›  技术社区  ›  Rajiv

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

  •  0
  • Rajiv  · 技术社区  · 8 年前

    我正在编写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循环中的链。链是否有办法在返回之前完成所有回调执行。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Louis    8 年前

    你的目标是回报一个只会解决一次的承诺 全部的 循环中执行的工作已完成。然而,这不是你正在做的。你的问题是:

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

    为了使代码工作,必须将异步操作分配给 chain 之前 这个 return 语句执行。但异步操作不是这样工作的。当你调用任何异步方法时,你只是 安排异步操作以供将来执行 . 它将在未来的某个时候执行, 但绝对不是马上 . 在您拥有的代码中,您计划了一个异步操作,并立即返回 链条 的价值 链条 你回来了 不能 您的循环尚未执行。

    你应该做如下的事情。重要的是在循环内创建一个操作链 把链条还给我 从传递给的函数 .then 因此,最重要的承诺取决于您在循环中创建的链。这样,你从你的方法中得到的承诺 必须等待所有内部操作完成后才能解决。

    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 对于循环,可以去掉循环中立即调用的arrow函数,它似乎只是为了确保循环中的闭包获得 i (而不是使用的最后一个值执行所有 ).