无法访问onResourceRequested回调内变量?如何传递外部变量求解
解决PhantomJS中onResourceRequested回调访问外部变量的问题
这个问题本质是JavaScript作用域与回调上下文绑定的问题——onResourceRequested的默认回调函数不会自动继承外层作用域的变量,不过有几种简单可靠的解决办法:
方法1:使用ES6箭头函数(推荐)
箭头函数不会创建自己的独立作用域,会直接继承外层上下文的变量,所以能轻松访问到testvar:
var phantom = require("phantom"); var _ph, _page, _outObj; phantom.create().then(function(ph){ _ph = ph; return _ph.createPage(); }).then(function(page){ _page = page; var testvar = "WHY THIS IS NOT PRINTING"; // 用箭头函数作为回调 _page.property('onResourceRequested', (requestData, networkRequest) => { console.log(testvar); // 现在能正常打印了! // 这里可以添加你的其他逻辑,比如取消请求、打印请求URL等 }); // 后续页面操作示例 return _page.open('https://example.com'); }).then(function(status){ console.log('页面加载状态:', status); _ph.exit(); }).catch(function(err){ console.error('出错了:', err); _ph.exit(); });
方法2:使用闭包绑定变量
如果你的运行环境不支持ES6,也可以用闭包把外部变量“包裹”进回调函数里:
// 在createPage的then回调内部 var testvar = "WHY THIS IS NOT PRINTING"; // 定义一个返回回调的函数,把testvar作为参数传入 function createRequestHandler(outerVar) { return function(requestData, networkRequest) { console.log(outerVar); // 访问传入的外部变量 } } // 给onResourceRequested赋值闭包返回的函数 _page.property('onResourceRequested', createRequestHandler(testvar));
方法3:用bind绑定上下文
还可以通过Function.prototype.bind()给回调函数绑定一个包含外部变量的上下文对象:
// 在createPage的then回调内部 var testvar = "WHY THIS IS NOT PRINTING"; _page.property('onResourceRequested', function(requestData, networkRequest) { console.log(this.testvar); // 通过this访问绑定的变量 }.bind({ testvar: testvar })); // 把testvar绑定到回调的this上下文上
原代码无法访问的原因
如果用普通函数作为onResourceRequested的回调,这个函数的作用域是由PhantomJS内部调用时决定的,并非你定义testvar的外层作用域,所以自然拿不到testvar的值。上面的三种方法都是通过不同方式让回调函数能“捕获”到外层作用域的变量。
内容的提问来源于stack exchange,提问作者CrazyProgrammer
相关产品推荐
相关产品推荐

