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
的最后一个值)。
我正在编写 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
的最后一个值)。