Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Phantomjs page.evaluate和q延迟问题_Javascript_Phantomjs_Q - Fatal编程技术网

Javascript Phantomjs page.evaluate和q延迟问题

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;

我试图将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;
};
下面是错误

看起来它无法找到在外部范围中定义的延迟变量,这很奇怪。同样的代码也适用于具有回调功能的其他方法,如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
}