评估中的例外情况

时间:2012-05-15 11:47:40

标签: javascript phantomjs

我正在尝试与编码相当糟糕且速度非常慢的网站进行互动。我将用一个例子说明我遇到的问题:

在这个网页上有2个选择框,第一个用于选择国家/地区,更改了对网络服务器的AJAX请求,后者又返回城市列表。此列表用于填充第二个选择框。现在问题是我可以使用phanomtjs'页面对象中的evaluate函数迭代第一个选择框并选择正确的选项。但之后我必须等待n秒才能填充第二个框。目前我通过设置一个等待25秒的计时器来解决这个问题,然后从第二个框中选择城市。然而,这是一个非常糟糕的解决方案。首先,25秒在所有情况下都不够长,因此有时会超时并失败。第二个问题是,在大多数情况下,25秒太长了。

所以我必须找到一种方法来等待第二个盒子被填充。起初我虽然可以在evaluate函数中使用setInterval来测试是否填充了选择框。这有效,但是有一个问题,因为setInterval是异步的,使用这种方法我失去了找出是否可以做出正确选择的能力。为了说明我的意思,下面的代码是我不必等待时的工作方式:

var retval = page.evaluate(function () {
    return selectOption('select_id',
                        info['country']);
});

selectOption是一个迭代select元素的函数,直到它找到正确的选项元素,如果失败则返回false,然后由赋值函数返回此返回值,以便检查它是否有效。

另一种选择是在网页的上下文中使用setInterval进行等待,如果失败则引发异常。我尝试过这样做,但我似乎无法捕获网站范围之外的异常。 PhantomJS在终端中转储异常,但是我无法拦截它。

这有什么办法吗?或者我应该使用固定等待时间选项吗?

编辑:我尝试使用page.onError,但它似乎没有被使用。

1 个答案:

答案 0 :(得分:0)

我还需要找出在评估函数中是否抛出异常。我设法通过添加另一个用try-catch包装函数的层来实现这个目的:

// Wrap a function (func) inside a try-catch block and return
// the exception if any. Otherwise return null. The ctx is a
// a bucket for all the variables to be passed to func.
var tryCatchWrapper = function(func, ctx) {        
    try {
        funct(ctx);
    }
    catch(e) {
        return e;
    }

    return null;
}

然后评估somefunction我就这样使用它:

var error = page.evaluate(tryCatchWrapper, somefunction);
if (error) {
    handle error...
}

如果我希望将参数传递给func,那么我使用上下文对象。有关如何将变量参数传递给函数的不同方法,请查看问题:"JavaScript variable number of arguments to function"