2016-04-27 2 views
0

Прямо сейчас, что я делаю, используется установка интервала для поиска изменений. Если есть какие-либо изменения, мой скрипт предупредит меня, и если нет, он будет ждать одну секунду, а затем снова проверить. Есть лучший способ сделать это? Информация, которую ищет мой скрипт, чувствительна к времени, поэтому, если скрипт предупреждает меня слишком медленно, я не смогу ничего сделать с информацией. Так что я спрашиваю, есть ли лучший подход, поэтому я могу быть в курсе любых изменений, как только это произойдет?Лучший способ очистить информацию, чувствительную к времени?

Код:

page.open(url) 
timer = Date.now(); 
do{ 
if(Date.now()-timer>=1000){ 
//Look for change 
} 
timer =Date.now() 
}while (no chnages) 

ответ

0

PhantomJS не работает при использовании синхронного цикла, как в вашем случае. Поскольку JavaScript является однопоточным, это блокирует выполнение.

с задержкой

Можно, конечно, использовать setTimeout или setInterval для этого случая:

var interval = 1000; // change according to needs 
page.open(url, function(){ 
    setTimeout(function retry(){ 
     var condition = page.evaluate(...); 
     if (!condition) { 
      setTimeout(retry, interval); 
     } else { 
      // TODO: what to do on success 
     } 
    }, interval); 
}); 

setInterval пример будет выглядеть так же. Фактически, это то, что делает waitFor() в папке примеров PhantomJS. Проблема с этими подходами, конечно, является возможной задержкой между изменением и уведомлением об этом изменении. Разумеется, вы можете уменьшить интервал повтора, пока вы больше не увидите никакой разницы.

без задержки

Есть по крайней мере два способа обнаружения изменения без задержки.

  • Регистрация на page.onResourceReceived event и попытаться определить, является ли (это не возможно смотреть в тело запроса) изменение, которое вы заинтересованы в случилось с ограниченной информацией.

  • В PhantomJS 2.x (в 1.x, возможно, с префиксом), вы можете создать MutationObserver искать изменения в DOM в контексте страницы (в page.evaluate()), а затем вы посылаете немедленное уведомление от контекст страницы (из обработчика события MutationObserver) во внешний контекст, используя window.callPhantom and page.onCallback pair.

1

Если ресурс вы выборка правильно установки последнего изменения заголовка, он может быть более эффективным, чтобы сделать запрос HTTP HEAD, первым, и только открыть страницу в PhantomJS, если он был изменен. Это определенно будет более сложным, поэтому сначала стоит проверить другие варианты.

Код примера, который проверяет время последней модификации на http://stackoverflow.com, выглядит следующим образом.

var url = 'http://stackoverflow.com'; 
var page = require('webpage').create(); 
var interval = 1000; // change according to needs 
var previousLastModified; 
(function modifiedCheck() { 
    var xhr = new XMLHttpRequest(); 
    xhr.onreadystatechange = function() { 
     if (xhr.readyState == 4 && xhr.status == 200) { 
      var lastModified = xhr.getResponseHeader("Last-Modified"); 
      if (lastModified !== previousLastModified) { 
       page.open(url, function(status) { 
        if (status === 'success') { 
         previousLastModified = lastModified; 
         // TODO: do something with fetched page 
         console.log('fetched page.'); 
        } 
        setTimeout(modifiedCheck, interval); 
       }); 
      } else { 
       setTimeout(modifiedCheck, interval); 
      } 
     } 
    }; 
    console.log('making HEAD request.'); 
    xhr.open('HEAD', url); 
    xhr.send(); 
})(); 

Вы можете видеть из консоли, что страница кэшируется в течение 1 минуты.

Функция самоисполняемого modifiedCheck в этом примере использует анонимные функции для асинхронного обработки как результата вызова AJAX, так и загрузки страницы PhantomJS, что ограничивает блокировку.

Обратите внимание, что вам необходимо запустить PhantomJS с опцией --web-security=false, чтобы позволить вызову AJAX выполнять без ошибок.

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