2016-09-20 70 views
0

我有這個功能。基本上,它從數據庫中搜索數據,並用它做一些事情。在這個演示中,它只是增加計數器。在Node.js中添加延遲('data')執行

exports.fullThreads = function(){ 
    return new Promise((resolve, reject) => { 
    MongoClient.connect(mongoUrl, (err, db) => { 
     var fullThreads = db.collection('tmp_fullThreads'), 
      threadPages = db.collection('tmp_threadPages').find(); 

     var counter = 0; 

     threadPages.on('data', (doc) => { 
     setTimeout(function(){ 
      counter++; 
     }, 200) 
     }); 

     threadPages.on('end',() => { 
     console.log('end'); 
     console.log(counter); 
     }); 

    });//connect 
    });//promise 
}//fullthreads 

在這個例子中,我預計它會調用數據,等待200ms,然後增加計數器。一旦達到目的,它就會結束。但它是不同的。在on('data')實際完成之前調用on('end')。我想這是因爲它沒有立即返回值。所以這個setTimeout函數不是一種方法。不過,我在這裏遇到了一個問題。這太簡單了,在現實生活中,這不會增加計數器,它會調用外部API,因爲它在很短的時間內不能接受太多的調用,所以我想在每次調用之間做一個延遲,這樣做是否正確?

+1

您是否嘗試過使用streams2方法(例如'threadPages.read()'和''readable''事件)而不是使用''data''事件處理程序?否則,你應該能夠根據需要手動'暫停()'和'恢復()'流。 – mscdex

回答

0

這是我的解決方法:

var threadPages = db.collection('tmp_threadPages').find(); 
    var delay = 0; 

    function test(doc, delay){ 
    setTimeout(function(){ 
     console.log(delay); 
    }, delay) 
    } 

    threadPages.on('data', (doc) => { 
    test(doc, delay); 
    delay += 100; 
    }); 

它運作良好,如果你並不需要正確的事件綁定到on('end方法。基本上,它會增加每個請求的延遲時間,否則它會立即觸發所有請求。這會使代碼變慢,並且每秒請求的請求數量不會過多。

0

那麼你就需要某種queu 如:

queuTasks = []; 
queuTasks.push("Task1"); 
queuTasks.push("Task2"); 

function doTasks(){ 

    // Do your task 
    if(queuTasks.length > 0){ 
     console.log(queuTasks[0]); 
     queuTasks.splice(0,1); // Remove it from the queu 
    } 
    setTimeout(function(){ doTasks();}, 1000); 
} 

這僅僅是一些簡單的代碼,我做了,可能不起作用開箱即用。但是你認爲你明白了。

我知道這不完全是你問的什麼