Javascript Phantomjs page.evaluate和q延迟问题
我试图将Q promise库与PhantomJS一起使用,但下面的代码不起作用Javascript Phantomjs page.evaluate和q延迟问题,javascript,phantomjs,q,Javascript,Phantomjs,Q,我试图将Q promise库与PhantomJS一起使用,但下面的代码不起作用 app.evaluate_page=function(page){ var deferred = q.defer(); console.log("Before the page evaluation"); page.evaluate(function(){ deferred.resolve(page); }); return deferred.promise;
app.evaluate_page=function(page){
var deferred = q.defer();
console.log("Before the page evaluation");
page.evaluate(function(){
deferred.resolve(page);
});
return deferred.promise;
};
下面是错误
看起来它无法找到在外部范围中定义的延迟变量,这很奇怪。同样的代码也适用于具有回调功能的其他方法,如page.open方法
下面的代码正如预期的那样工作,不确定上面的代码为什么不工作
page.evaluate在浏览器进程中运行,无法访问变量
您可以同步使用page变量,因此这里不需要承诺。正如@slaks提到的,page.evaluate回调函数在沙盒环境中运行 第页明确指出,第页评估: 在网页上下文中计算给定函数。这个 执行是沙盒,网页无法访问幻影 对象,它无法探测自己的设置 然而,您可以将参数传入和传出,但正如所述: 注意:参数和evaluate函数的返回值必须 是一个简单的原始对象。经验法则:如果可以的话 通过JSON序列化,就可以了 截至2016年10月,深入研究这一主题,这似乎是一个悬而未决的问题 github上有一个关于使用page.evaluate启用承诺的公开问题: 有一个实验性api可以从网页上下文启用回调函数: 等待网页准备就绪的官方方法是扩展 我使用第三种方法的个人混合 这是我的main.js文件: 以及lib/waitFor.js文件,它只是phantomjs中waifFor函数的复制和粘贴:
此方法不是异步的,但至少我可以保证在尝试使用它们之前已加载所有资源。您希望实现什么?page.evaluate是同步的。是的。我希望page.evaluate是同步的。是的,所以为什么需要q?哦,好的。我不确定。让我同步使用它,看看它是如何工作的。谢谢,page.open也是同步的吗?
Before the page evaluation
ReferenceError: Can't find variable: deferred
phantomjs://webpage.evaluate():2
phantomjs://webpage.evaluate():3
phantomjs://webpage.evaluate():3
app.openPage = function(options){
var deferred = q.defer();
page.open(options.url,function(status){
if(status!=="success"){
deferred.reject(new Error("Page could not be loaded at "+ options.url ));
}
else {
deferred.resolve(page);
}
});
return deferred.promise;
};
'use strict';
var wasSuccessful = phantom.injectJs('./lib/waitFor.js');
var page = require('webpage').create();
page.open('http://foo.com', function(status) {
if (status === 'success') {
page.includeJs('https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js', function() {
waitFor(function() {
return page.evaluate(function() {
if ('complete' === document.readyState) {
return true;
}
return false;
});
}, function() {
var fooText = page.evaluate(function() {
return $('#foo').text();
});
phantom.exit();
});
});
} else {
console.log('error');
phantom.exit(1);
}
});
function waitFor(testFx, onReady, timeOutMillis) {
var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000, //< Default Max Timout is 3s
start = new Date().getTime(),
condition = false,
interval = setInterval(function() {
if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
// If not time-out yet and condition not yet fulfilled
condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
} else {
if(!condition) {
// If condition still not fulfilled (timeout but condition is 'false')
console.log("'waitFor()' timeout");
phantom.exit(1);
} else {
// Condition fulfilled (timeout and/or condition is 'true')
// console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condi>
clearInterval(interval); //< Stop this interval
}
}
}, 250); //< repeat check every 250ms
}