Как вернуть значение из функции async / await? - PullRequest
0 голосов
/ 26 сентября 2018

Использование кукловода для сбора данных с двух разных веб-страниц в массивы для последующего сравнения.Однако программа не ожидает возвращенного массива перед переносом.

async function go(){
  try{
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('www.webpage.com');

    const tds = await page.$$('td');
    const data = [];
    for (let i = 0; i < tds.length; i++){
      const td = tds[i];
      const tdcontent = await page.evaluate(td => td.innerText, td);
      if (tdcontent.length > 5) {
        data[i] = {"content": tdcontent};
      }
    }
    return data;
  } catch (e) {
     console.log(e);
  }
};

(async function main(){
  const returnedData = await go();
  console.log(returnedData.length);
})();

Возвращаемое значение data.length равно 0.Новое в nodejs и async структура программирования.Я думаю, это потому, что .length регистрируется до того, как возвращается data?

как мне вернуть данные таким образом, чтобы можно было манипулировать ими и завершить мои сравнения?

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Я стараюсь не использовать page.$$ в таких случаях.Вместо этого я использую document.querySelectorAll и сопоставляю элементы и извлекаю текст.

Вот модифицированный код:

const getTdData = async () => {
  try {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto("http://example.com");

    return page.evaluate(() => {
      // get all td elements
      const tdList = [...document.querySelectorAll("td")]; 
      return tdList.map(element => ({ content: element.textContent }));
    });
  } catch (e) {
    console.log(e);
  }
};

(async function main() {
  const returnedData = await getTdData();
  console.log(returnedData.length);
})();
0 голосов
/ 26 сентября 2018

Прежде всего, вы упускаете апостроф в вашей функции page.$$().Вы должны изменить это на:

const tds = await page.$$( 'td' );

Далее, вы пытаетесь передать несуществующую переменную в page.evaluate().Вы можете исправить это, передав tds[i] вместо td:

const tdcontent = await page.evaluate( td => td.innerText, tds[i] );

Ваш конечный результат должен выглядеть примерно так:

const go = async () =>
{
    try
    {
        const browser = await puppeteer.launch();
        const page    = await browser.newPage();

        await page.goto( 'www.webpage.com' );

        const tds  = await page.$$( 'td' );
        const data = [];

        for ( let i = 0; i < tds.length; i++ )
        {
            const tdcontent = await page.evaluate( td => td.innerText, tds[i] );

            if ( tdcontent.length > 5 )
            {
                data[i] = { content : tdcontent };
            }
        }

        return data;
    }

    catch ( e )
    {
        console.log( e );
    }
};

( async function main ()
{
    const returnedData = await go();

    console.log( returnedData.length );
})();

Если у вас по-прежнему возникают проблемы,Вы можете дождаться полной загрузки страницы, используя page.goto( ... , { waitUntil : 'networkidle0' }), или дождаться, пока соответствующий элемент будет добавлен в DOM, используя page.waitForSelector():

await page.goto( 'www.webpage.com' , { waitUntil : 'networkidle0' });
...
await page.waitForSelector( 'td' );
...