2013-10-02 76 views
2

我試圖在PhantomJS上構建一個非常簡單的解決方案,但在撥打phantom.exit()時它崩潰了。例如,運行下面的代碼時:PhantomJS在Linux上的phantom.exit()後崩潰

var page = require('webpage').create(); 
page.onResourceRequested = function (request) { 
    console.log('Request ' + request.url); 
    phantom.exit(); 
}; 
page.open('http://www.google.com/'); 

崩潰,並在Ubuntu(12.04.3 LTS)和CentOS(6.4)段故障。如果我註釋掉phantom.exit()它會列出請求的URL,因此它基本上按預期工作。但是phantom.exit()是我真正需要的,因爲我想在某些情況下終止我的腳本(例如,嘗試訪問特定域)。 我有一種感覺,我的問題太明顯了,但並不知道發生了什麼。

回答

7

這是a known issue,但有一個簡單的解決方法。不過,這是應該被修正了一個錯誤,但現在:

setTimeout(function() 
{ 
    phantom.exit(0); 
},0); 

這是愚蠢的,但應該做的伎倆...有GitHub的頁面我鏈接到一個補丁,太。還有一些關於爲什麼這個bug存在的更多細節。
我認爲問題就出在這裏:

是的,你是對的,但每次調用m_pages [I] - >關閉(); [phantom.exit應終止PhantomJS不執行任何進一步的代碼。]調用deleteLater()這意味着每個對象將被刪除,但異步...也許這是問題。

異步刪除在我看來是錯誤的可能原因,因爲處理程序setTimeout後返回,而實際exit調用將被延遲,一切都可以被刪除的時間和地點應該是。超時有效的移動電話exit處理程序的範圍......
我沒有測試它的外面,但如果是這樣的話,或許比:

var closeFunc = function() 
{ 
    phantom.exit(0); 
}; 
page.onResourceRequested = function (request) 
{ 
    console.log('Request ' + request.url); 
    return closeFunc(); 
}; 

會的工作了。如果確實如此,則只需使用這些解決方法中的任何一種,直到發佈可靠的補丁或下一個版本,並且該錯誤得到修復。

+0

謝謝@Elias,第二個解決方案崩潰,但setTimeout工作正常。當然,在我發佈信息之前,我已經搜索了Google,並且看到了類似的解決方案......但是這是2012年的討論,我絕對不會認爲這樣的關鍵問題在一年之後仍然沒有解決! – Eugene

+0

現在是2015年,接近2016年,我有同樣的問題:( – siliconrockstar

+1

@siliconrockstar:這實際上是一個非常棘手的問題,這是JS處理回調的方法固有的問題:有一個調用隊列,它會間歇性地檢查。如果直接調用'phantom.exit(0);',調用隊列可能不是空的。使用'setTimeout'將'phantom.exit(0)'調用推到該隊列的末尾,確保所有掛起的調用都是執行......這不是一個像語言設計那樣的錯誤 –