为什么等待 Selenium getAttribute 仍然是 return 一个承诺?

Why does awaiting Selenium getAttribute still return a promise?

我正在为 JavaScript 使用 Selenium 并尝试创建一个包含表单输入值的数组。我知道 getAttribute(以及大多数其他方法)return 是一个 Promise。但是,为什么 values 数组 Promises 中的值即使我调用了 await

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> } ]

getAttribute 上调用 await 不会产生值吗?

(是的,我知道代码看起来有点奇怪。我试图弄清楚如何在 forEach 循环中调用 expect 而不会得到 UnhandledPromiseRejectionWarning -- 但是这是另一个 post 的问题。)

为了解释为什么会这样,让我再举一个例子:

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');
    });
});

在这种情况下,您会期望 values 是一个承诺列表,它确实是。

您遇到的问题 运行 是的,您正在等待结果。然而,异步函数总是 returns 一个承诺。 map 没有做任何事情来解决这个承诺。在这种情况下,传递给 map 的函数中的 await 实际上没有做任何事情。相反,您需要这样做:

const value_promises = inputs.map((input) => {
    return input.getAttribute('value');
});
const values = await Promise.all(value_promises);

Promise.all 专为这种情况而设计,您有一个 Promise 列表,并且您想要获取它们的值。