javascript - Puppeteer - 有没有办法将函数作为参数传递给通过exposeFunction 加载的函数?
问题描述
我有一个使用 puppeteer 的节点 js 项目,我想在页面上下文中使用库 async-wait-until。这个库接收一个函数作为参数,尝试运行它直到它返回一个真实值或超时。
问题是我收到以下错误:错误:谓词不是具有谓词的函数,该函数的变量名称包含该函数。
一些代码:这是我启动页面的地方 - 我公开函数的地方:
const waitUntil = require('async-wait-until');
// const waitUntil = require('./node_modules/async-wait-until/src/waitUntil.js');
await page.exposeFunction('waitUntil', waitUntil);
在这里,我正在尝试运行该功能
try {
await waitUntil(() => {
//Code should come here
return false;
}, 25000, 1000);
console.log('Element Is Ready');
} catch (e) {
console.log('CATCH');
console.log(e.toString());
}
这里是导出函数waitUntil的内部js文件:
var DEFAULT_INTERVAL = 50;
var DEFAULT_TIMEOUT = 5000;
/**
* Waits for predicate to be truthy and resolves a Promise
*
* @param predicate Function Predicate that checks the condition
* @param timeout Number Maximum wait interval, 5000ms by default
* @param interval Number Wait interval, 50ms by default
* @return Promise Promise to return a callback result
*/
module.exports = function waitUntil(
predicate,
timeout,
interval
) {
var timerInterval = interval || DEFAULT_INTERVAL;
var timerTimeout = timeout || DEFAULT_TIMEOUT;
return new Promise(function promiseCallback(resolve, reject) {
var timer;
var timeoutTimer;
var clearTimers;
var doStep;
clearTimers = function clearWaitTimers() {
clearTimeout(timeoutTimer);
clearInterval(timer);
};
doStep = function doTimerStep() {
var result;
try {
console.log('running predicate function');
console.log(predicate);
console.log(timeout);
console.log(interval);
result = predicate();
console.log('ran predicate function');
if (result) {
clearTimers();
resolve(result);
} else {
timer = setTimeout(doStep, timerInterval);
}
} catch (e) {
clearTimers();
reject(e);
}
};
timer = setTimeout(doStep, timerInterval);
timeoutTimer = setTimeout(function onTimeout() {
clearTimers();
reject(new Error('Timed out after waiting for ' + timerTimeout + 'ms'));
}, timerTimeout);
});
};
运行代码时,我得到的打印结果是: null 25000 1000
含义谓词(正在发送的函数)被识别为空。尝试了所有不同的方式(将其保存为函数/函数表达式/匿名函数,没有异步),没有任何效果。
当发送字符串而不是函数时,打印会打印字符串本身,而不是 null。
有什么我做错了吗?有没有办法绕过它?
谢谢
解决方案
看起来,暴露的函数,以及评估的函数,只能使用可序列化的参数,所以函数不能作为参数在 Node.js 和浏览器上下文之间传输。也许你可以尝试一个包装器和一个函数字典,这样你就可以将函数名作为字符串传递:
const waitUntil = require('async-wait-until');
const functions = {
foo() {
//Code should come here
return false;
},
bar() {
//Code should come here
return false;
},
};
await page.exposeFunction('waitUntil', async (functionName, param1, param2) => {
waitUntil(functions[functionName], param1, param2);
});
await page.evaluate(() => {
await window.waitUntil('foo', 25000, 1000);
});
推荐阅读
- firebase-storage - 将一些图像上传到 Google 存储时出现重试限制超出错误
- typescript - 如何通过 Yarn Workspaces 在 NestJS 中进行代码共享
- excel - 突出显示范围内的空白单元格
- java - 根据索引位置或 id 合并数组元素
- javascript - 使用 Node Cron 的异步函数
- google-sheets - 根据一列的前 5 个提取两列值,而不抓取其余列
- r - 将“总体”列添加到 R 中的汇总表
- sql - SQL Server:删除所有数据库表中的所有 Not Null 约束
- google-apps-script - TypeError:无法读取未定义的属性“0”(Google 表格/应用程序脚本)
- javascript - 使用 JQuery 从下拉列表中获取选定的值并将其保存在数据库中