ссылка на документ в методе кукловода - PullRequest
1 голос
/ 14 июня 2019

Меня смущает метод document в методе кукловода evaluate.Официальный документ имеет следующий код:В функции waitFor в сценарии узла есть ссылка на документ.Я понимаю, что эти строки, вероятно, будут выполнены как: waitForHandler.toString(), а затем передаются в среду браузера для запуска через соединения WebSocket.В любом случае, документ и некоторые другие переменные, такие как window, вызывают путаницу, когда они появляются в скрипте узла, не так ли?Любые объяснения по этому поводу?

await page.waitFor(() => !!document.querySelector('.foo'));

1 Ответ

1 голос
/ 14 июня 2019

Да, вы очень правы, это может вызвать путаницу.

Пример

const document = /* ... */;
await page.waitFor(() => !!document.querySelector('.foo'));

Похоже, код обращается к переменной document извыше, но на самом деле это не то, что происходит здесь, даже если ваша подсветка IDE / синтаксиса может сообщать вам ту же самую переменную.

Пояснение

Среда Node.jsи среда браузера - это две отдельные (JavaScript) среды, которые взаимодействуют через WebSocket.Поэтому, когда вы выполняете функцию на странице в вашей среде Node.js, кукловод должен отправить функцию в браузер в виде строки.Для этого кукловод вызовет функцию toString() для данной функции, которая просто возвращает ваш код высокого уровня, как вы его записали.Эта строка будет отправлена ​​в браузер и выполнена в его окружении.

Это также причина, по которой вы можете передать строку кукловоду вместо функции.Если вы отправите строку вместо функции, код будет выполнен в том же виде, что и в среде браузера.

Чтобы привести пример для этого, рассмотрим эти две строки, которые делают то же самое (print 123на консоль):

console.log(await page.evaluate(() => 123));
console.log(await page.evaluate('(() => 123)()'));

В первой строке функция передается как функция (и кукловод преобразует ее в строку и вызывает функцию для вас).Во второй строке передается та же функция, но на этот раз мы должны вызывать ее самостоятельно (дополнительные скобки вокруг функций нужны только по синтаксическим соображениям).

Почему это работаеткак это?

Puppeteer позволяет передавать функции как функции (а не только как строки) для удобства.Это позволяет легко обнаружить любые незначительные ошибки, такие как отсутствие круглых скобок, поскольку они уже обнаружены вашей средой Node.js (ваш "Node.js JavaScript Parser" все равно будет анализировать вашу функцию).Также это упрощает использование подсветки синтаксиса в вашем редакторе кода.

Но да, легко забыть, что этот уровень абстракции означает, что любой аргумент, который вы используете, должен быть передан как отдельный аргумент, подобный этому:

const value1 = 123;
await page.evaluate((value1) => { /... */ }, value1);

Подводя итог, если вы находите это запутанным, вы всегда можете поместить свой код в отдельный файл, прочитать этот файл и передать его содержимое в виде строки при вызове функций кукловода.Это позволяет лучше отделить ваш код.Стоит ли усилий?Вы сами должны решить это ...

...