为了账号安全,请及时绑定邮箱和手机立即绑定

Javascript Promise 和控制台日志?

Javascript Promise 和控制台日志?

Helenr 2022-07-08 15:48:18
我需要有关 Javascript Promises 的帮助。-buttons是一个节点列表。我从puppeteer(API)得到它。我需要一个带有特定文本的按钮列表。我转换buttons为真实按钮数组(page.evaluate API 链接):我通过数组映射,将其转换为按钮,检查文本,return null如果文本不是我需要的我console.log是按钮文本 - 它向我显示了我需要的文本 - 所以一切都很好。然后我增加counter并返回转换后的按钮。之后我过滤数组 - 检查非空元素。我希望goodButtons它只包含我需要的按钮 - 带有正确的文本。但输出是buttons 328button: Confirmbutton: Confirm... 100 lines of "good button text" in totalbutton: Confirmcounter 0good 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 328counter 149good buttons 328
查看完整描述

2 回答

?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

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


查看完整回答
反对 回复 2022-07-08
?
慕虎7371278

TA贡献1802条经验 获得超4个赞

async函数返回一个承诺。


因此buttons.map( async function)返回一个promise数组,其中一些已经实现null(通过null从map函数返回),而所有其他的已经通过返回button提供给map函数的元素句柄来实现。


您可以使用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它。


同样button,在 puppeteer elementHandle 对象中,如果我正确阅读了文档,这不是一个承诺,所以它也不应该await在它之前要求。


(编辑:感谢 Andrew P. - filter 函数必须应用于返回的数组await Promise.all(....)


查看完整回答
反对 回复 2022-07-08
  • 2 回答
  • 0 关注
  • 131 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信