Protractor函数调用后返回空数组,请求排查代码错误
问题分析与修复方案
你的代码里有几个关键问题导致返回空数组,我来逐个拆解:
1. 异步操作的时序错误
Protractor的所有元素操作(比如each、getAttribute)都是异步的,依赖Promise来完成。你现在的代码里,console.log(arrVal.len)是同步执行的,这时候each循环里的getAttribute还没完成,arrVal自然还是空数组。
2. 数组长度属性拼写错误
你写的arrVal.len是错误的,JavaScript里数组的长度属性是length,这会导致你打印的是undefined而不是数组长度。
3. 未声明的全局变量
elem没有用let/const/var声明,会变成全局变量,虽然这不是空数组的直接原因,但这是不好的编码习惯,容易引发其他问题。
修复后的代码
我们可以用element.all的map方法来更优雅地处理异步,它会自动收集所有Promise的结果,不需要手动维护数组:
function() { return element.all(by.xpath('//div[contains(@class,"header-col")]/div')) .map(function(elementVar) { return elementVar.getAttribute('title').then(function(val) { return val.toString(); }); }) .then(function(arrVal) { console.log(arrVal.length); // 现在能正确打印数组长度 return arrVal; // 返回填充好的数组 }); }
为什么这样能行?
map方法会遍历所有元素,对每个元素执行异步操作后收集结果,返回一个Promise,当所有异步操作完成后,Promise会resolve为填充好的数组。- 我们在
then里处理最终的数组,确保所有异步操作都完成后再访问它,这样就不会出现空数组的问题。
如果你一定要用each的话,也可以手动用Promise来控制时序:
function() { const arrVal = []; const elem = element.all(by.xpath('//div[contains(@class,"header-col")]/div')); return elem.each(function(elementVar) { return elementVar.getAttribute('title').then(function(val) { arrVal.push(val.toString()); }); }).then(function() { console.log(arrVal.length); return arrVal; }); }
这里的关键是return elem.each(...),然后在它的then里访问arrVal,因为each会返回一个Promise,当所有循环里的异步操作完成后才会resolve。
内容的提问来源于stack exchange,提问作者Rufus Lawrence
相关产品推荐
相关产品推荐

