1 回答

TA貢獻(xiàn)1852條經(jīng)驗(yàn) 獲得超1個(gè)贊
是的,你說得很對(duì),這可能會(huì)引起混淆。
例子
const document = /* ... */;
await page.waitFor(() => !!document.querySelector('.foo'));
看起來代碼正在document從上面訪問變量,但這實(shí)際上并不是這里發(fā)生的事情,即使您的 IDE/語法高亮可能會(huì)告訴您它是相同的變量。
解釋
Node.js 環(huán)境和瀏覽器環(huán)境是兩個(gè)獨(dú)立的 (JavaScript) 環(huán)境,它們通過 WebSocket 進(jìn)行通信。因此,當(dāng)您在 Node.js 環(huán)境中的頁面上執(zhí)行函數(shù)時(shí),puppeteer 需要將該函數(shù)作為字符串發(fā)送到瀏覽器。對(duì)于這個(gè)puppeteer 將調(diào)用toString()給定函數(shù)上的函數(shù),該函數(shù)只返回您寫下的高級(jí)代碼。該字符串將被發(fā)送到瀏覽器并在其環(huán)境中執(zhí)行。
這也是您可以將字符串而不是函數(shù)傳遞給 puppeteer 的原因。如果您提交的是字符串而不是函數(shù),則代碼將在瀏覽器環(huán)境中執(zhí)行。
舉個(gè)例子,考慮這兩行,它們做同樣的事情(打印123到控制臺(tái)):
console.log(await page.evaluate(() => 123));
console.log(await page.evaluate('(() => 123)()'));
在第一行中,該函數(shù)作為函數(shù)傳遞(并且 puppeteer 會(huì)將其轉(zhuǎn)換為字符串并為您調(diào)用該函數(shù))。在第二行中,傳遞了相同的函數(shù),但這次我們必須自己調(diào)用它(函數(shù)周圍的額外括號(hào)僅出于語法原因才需要)。
為什么它會(huì)這樣工作?
為方便起見,Puppeteer 允許將函數(shù)作為函數(shù)(而不僅僅是作為字符串)傳遞。允許這樣做,可以很容易地發(fā)現(xiàn)任何小錯(cuò)誤,例如缺少括號(hào),因?yàn)樗鼈円呀?jīng)被您的 Node.js 環(huán)境拾?。摹癗ode.js JavaScript Parser”仍將解析您的函數(shù))。此外,它還可以輕松地在您的代碼編輯器中使用語法高亮。
但是,是的,很容易忘記這個(gè)抽象層意味著您使用的任何參數(shù)都需要作為單獨(dú)的參數(shù)傳遞,如下所示:
const value1 = 123;
await page.evaluate((value1) => { /... */ }, value1);
總而言之,如果您發(fā)現(xiàn)它令人困惑,您始終可以將代碼放入一個(gè)單獨(dú)的文件中,讀取該文件并將其內(nèi)容作為字符串在調(diào)用 puppeteer 函數(shù)時(shí)傳遞。這允許更好地分離您的代碼。值得付出努力嗎?你必須自己決定...
添加回答
舉報(bào)