2013-10-02 3 views
2

Я попытался создать очень простое решение поверх PhantomJS, но как-то он сбой при вызове phantom.exit(). Например, при выполнении следующего кода:Сбой PhantomJS после phantom.exit() на Linux

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 я связан, тоже. Также есть некоторые подробности о том, почему эта ошибка существует.
Я думаю, что проблема лежит здесь:

Да, вы правы, но каждый вызов m_pages [я] -> Close(); [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) 'для завершения этой очереди, гарантируя, что все ожидающие вызовы были выполненный ... Это не так много, как по языковому дизайну –

Смежные вопросы