2012-11-22 61 views
1

我有一個基於Django的Web應用程序。我使用Scrapy Crawler來抓取網頁。目前,我的目標是能夠使用jQuery和AJAX請求從網頁內控制抓取工具。如何解決此ReferenceError?

我的理論體系如下:

  • 在網頁上,我有一個按鈕。當我點擊按鈕時,爬蟲程序在服務器端啓動。
  • 抓取工具啓動後,我會定期通過window.setInterval向服務器發送AJAX GET請求,以瞭解到目前爲止已抓取了多少個網頁。
  • 一旦爬蟲完成,GET請求應該停止使用window.clearInterval

這些是我當前的代碼的相關線路:

$(document).ready(function() { 

    // This variable will hold the ID returned by setInterval 
    var monitorCrawlerId; 

    $startCrawlerButton.on('click', function(event) { 

     // This function should be run periodically using setInterval 
     var monitorCrawler = function() { 

      $.ajax({ 

       type: 'GET', 
       url: '/monitor_crawler/', 
       // ... 
       success: function(response) { 

        // if the server sends the message that the crawler 
        // has stopped, use clearInterval to stop executing this function 
        if (response.crawler_status == 'finished') { 

         clearInterval(monitorCrawlerId); 

        } 

       } 

      }); 

     }; 

     // Here I send an AJAX POST request to the server to start the crawler 
     $.ajax({ 

      type: 'POST', 
      url: '/start_crawler/', 
      // ... 
      success: function(response) { 

       // If the form that the button belongs to validates correctly, 
       // call setInterval with the function monitorCrawler defined above 
       if (response.validation_status == 'success') { 

        monitorCrawlerId = setInterval('monitorCrawler()', 10000); 

       } 

      } 

     }); 

    }); 
}); 

問題:當我執行這個代碼,我得到這個在Firefox的Web控制檯:

ReferenceError: monitorCrawler is not defined 

的不過,奇怪的是,函數monitorCrawler無論如何得到定期執行。但每次執行時,我都會再次收到相同的錯誤消息。如果我在$startCrawlerButton.on()之外放monitorCrawler,我仍然會得到相同的錯誤。我該如何解決這個問題?由於我是一個JavaScript新手,任何幫助表示讚賞。非常感謝你!

回答

3

setInterval,當第一個參數是字符串時,在全局(window)上下文中解析。你可以給它一個變量指向要調用的函數或甚至:

setInterval(function(){monitorCrawler();}, 10000); 

這將創建一個封閉,當地變量monitorCrawler仍然存在,當時間間隔觸發。

+0

謝謝,伊戈爾。 :)這正是我需要的。通過這種方式,我可以將參數添加到'monitorCrawler()'中,在我的情況下這是必需的。由於您是第一個發佈此特定解決方案的人,因此我接受您的答案。 – pemistahl

1

嘗試

monitorCrawlerId = setInterval(monitorCrawler, 10000); 

使用參數:

monitorCrawlerId = setInterval(function(){ 
     //prepare params. 
     monitorCrawler(/* param1, param2*/); 
    }, 10000); 
+0

好的,這個工程,但以這種方式,我不能將任何參數傳遞給'monitorCrawler',對吧?我實際上需要在我的代碼中這樣做,但是在我的問題中留下了這個問題以保持簡單。 – pemistahl

+0

看到我的答案與匿名函數作爲第一個參數 – Igor

+0

對,你可以創建匿名函數@Igor說。 –

2

變化

setInterval('monitorCrawler()', 10000); 

setInterval(monitorCrawler, 10000); 

永遠不要傳遞字符串到setInterval,但函數引用!他們每次都是eval,而且在全球範圍內 - 但你的monitorCrawler函數對於點擊處理程序是本地的(我想通過「將它放在你的意思之外」來進入預備回調)。