我正在将Selenium用于JavaScript,并尝试创建一个包含表单输入值的数组。我知道getAttribute
(以及其他大多数方法)会返回Promise。但是,即使我叫values
,为什么await
数组中的值仍是Promises?
Then(/^The Author form should be empty$/, () => {
return driver.findElements(By.css('.author-form input')).then( (inputs) => {
expect(inputs.length).toBe(3)
let values = inputs.map(async (input) => await input.getAttribute('value'))
console.log("The values")
console.log(values)
values.forEach((value) => {
expect(value).toEqual('')
})
})
})
运行代码时,得到以下输出:
The values
[ Promise { <pending> }, Promise { <pending> }, Promise { <pending> } ]
在await
上调用getAttribute
不会产生值吗?
(是的,我知道代码看起来有些奇怪。我试图弄清楚如何在expect
循环内调用forEach
却没有得到UnhandledPromiseRejectionWarning
的声音,但这就是另一个帖子的问题。)
答案 0 :(得分:2)
为解释为什么会发生这种情况,让我提供另一个示例:
let values = inputs.map(async (input) => {
await input.getAttribute('value');
console.log('After await');
});
在没有异步等待的情况下,它将变为:
let values = inputs.map((input) => {
return input.getAttribute('value').then((result) => {
console.log('After await');
});
});
在这种情况下,您期望值是应许的列表。
您遇到的问题是,您正在等待结果。然而,异步函数总是返回一个promise。 map
无济于事。在这种情况下,传递给map的函数内部的await
实际上不执行任何操作。相反,您需要执行以下操作:
const value_promises = inputs.map((input) => {
return input.getAttribute('value');
});
const values = await Promise.all(value_promises);
Promise.all
专为这种情况而设计,您需要一个Promises列表,并希望获得其值。