我需要有关Javascript承诺的帮助。
buttons
-是一个NodeList。我从puppeteer
(API)那里得到的。
我需要带有特定文本的按钮列表。
我将buttons
转换为实际按钮数组(page.evaluate API link):
return null
console.log
按钮文字-它向我显示了我需要的文字-一切都很好。counter
之后,我过滤数组-检查是否为非null元素。
我希望goodButtons
仅包含我需要的按钮-带有正确的文本。
但是输出是
buttons 328
button: Confirm
button: Confirm
... 100 lines of "good button text" in total
button: Confirm
counter 0
good buttons 328
所以计数器不会一次增加(或者有async
/ await
的东西和我缺少的console.log
的窍门?)
但是,尽管我登录控制台的按钮文本似乎是正确的,但是goodButtons
数组似乎以某种方式包含了所有按钮。
代码
const buttons = await page.$$('button[type="button"]')
console.log('buttons', await buttons.length)
let counter = 0;
let goodButtons = await buttons.map(async button => {
const btnText = await page.evaluate(btn => btn.innerText, button);
if (!['Confirm'].includes(btnText)) return null
counter++
console.log('button: ', btnText)
return await button
}).filter(button => button !== null)
console.log('counter', counter)
console.log('good buttons', await goodButtons.length)
UPD (在Felix Kling评论之后)
let counter = 0;
let goodButtons = buttons.map(async button => {
const btnText = await page.evaluate(btn => btn.innerText, button);
if (!['Confirm', 'Подтвердить'].includes(btnText)) return null
counter++
return await button
})
goodButtons = await Promise.all(goodButtons)
goodButtons = goodButtons.filter(button => button !== null)
输出
buttons 328
counter 149
good buttons 328
答案 0 :(得分:1)
这是@Felix Kling的评论和@Ufuk的提示后的工作代码。
谢谢你们!
let counter = 0;
let goodButtons = buttons.map(async button => {
const btnText = await page.evaluate(btn => btn.innerText, button);
if (!['Confirm', 'Подтвердить'].includes(btnText)) return null
counter++
return await button
})
goodButtons = await Promise.all(goodButtons)
goodButtons = goodButtons.filter(button => button !== null)
输出
buttons 328
counter 149
good buttons 149
答案 1 :(得分:1)
async
函数返回承诺。
因此,buttons.map( async function)
返回一个诺言数组,其中一些已通过null
来实现(通过从map函数返回null
),而所有其他的诺言则通过返回来实现提供给map函数的button
元素句柄。
您可以使用Promise.all
将promise数组转换为可以从其中过滤null
值的数组:
let counter = 0;
let goodButtons = (await Promise.all(
buttons.map(async button => {
const btnText = await page.evaluate(btn => btn.innerText, button);
if (!['Confirm', 'Подтвердить'].includes(btnText)) return null
counter++
return button
}))
.filter(button => button !== null)
请注意,数组的length
属性是一个数字,因此无需await
。
类似地,在伪造的elementHandle对象中button
,如果我已正确阅读文档,也不是一个保证,因此也不应该在await
之前也需要await Promise.all(....
。
(编辑:感谢AndrewP。-必须将过滤器函数应用于数组
由<App>
<location id="1" />
<location id="2" />
<Location id="3">
<User loactionId="3">
</User>
</Location id="4">
</App>
返回)