我正在将Selenium与ChromeDriver一起使用Java编写刮板,并且希望将其包装到Observable中(以简化异步操作)。这是从我的解析器类返回Observable的代码:
return Observable.interval(5000, 5000, TimeUnit.MILLISECONDS)
.doOnSubscribe(ignored -> initialize())
.doOnNext(ignored -> refreshPage())
.map(ignored -> getHtml())
.map(this::parse)
.flatMap(Observable::fromIterable)
.doFinally(() -> finish())
.share();
因此,initialize()
在这里基本上创建了Selenium WebDriver的配置实例,refreshPage()
重新加载页面并等待其加载,getHtml()
只是driver.getPageSource()
和{{ 1}}是finish()
,其中driver.quit()
是Selenium WebDriver的实例。我遇到的问题是当我订阅此Observable并随后对其进行处置时。我从driver
得到一个异常,它说我在refreshPage()
之后在driver
上调用了一个方法(或者在上面的代码中,这意味着driver.quit()
在refreshPage()
之后被调用了) )。
我应该如何创建/修改可观察的源,以便在处置时正确释放我的资源? (我希望finish()
总是在Observable链中的所有其他操作完成后才被调用)。
更新:
我的finish()
函数是:
finish()
答案 0 :(得分:1)
doFinally
会引起您的怀疑。它在以下时间执行关联的Action
onError
,onComplete
或但是,我怀疑正在发生 是因为您可能是在driver.quit()
的正文中调用finish()
,而不是在返回的Action
中调用。假设在driver
中使用了refreshPage()
,则该错误是有道理的,因为doFinally()
本身(而不是返回的Action
)的实际调用是尽早完成的,以建立流行为,并且refreshPage()
是之后使用driver
的流中最早的点。
如果您的代码看起来像这样:
private Action finish() {
driver.quit();
return () -> {
...
};
}
...然后将对quit()
的调用移至Action
主体内,例如:
private Action finish() {
return () -> {
driver.quit();
};
}
如果我的假设是错误的,可以用finish()
的代码更新问题吗?我很想知道那里发生了什么。