【发布时间】:2020-04-20 17:04:48
【问题描述】:
我需要有关 Javascript Promises 的帮助。
buttons - 是一个 NodeList。我是从puppeteer (API) 那里得到的。
我需要一个带有特定文本的按钮列表。
我将buttons 转换为真实按钮数组(page.evaluate API link):
- 我通过数组映射,
- 将其转换为按钮,
- 检查文本,如果文本不是我需要的,请检查
return null - 我
console.log按钮文本 - 它显示了我需要的文本 - 所以一切都很好。 - 然后我增加
counter - 并返回转换后的按钮。
之后我过滤数组 - 检查非空元素。
我希望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
【问题讨论】:
-
Array#map不返回承诺。您需要使用Promise.all。.filter调用中的button实际上是指一个promise,它始终是!== null。 -
您能说得更具体一点吗? @FelixKling 我把它改成了
goodButtons = await Promise.all(goodButtons)现在counter工作了——它显示了很好的按钮数量。但是goodButtons数组仍然包含所有 328 个元素。感谢您的快速回复。 -
我用新代码和输出更新了问题
-
Promise.all 之后你不会过滤更新后的代码
标签: javascript promise async-await puppeteer