2014-05-01 43 views
0

我想寫一個小的守護進程,檢查是否有郵件發送,如果需要做睡眠X秒。NodeJS:不希望異步comportment

我不是很熟悉NodeJS的異步方式。所以我迷路了。

var sleep = require('sleep'); 

function getMailToSend(callback){ 
    [...] 
} 

function sendmail(mail, callback) { 
    [...] 
} 

while(true){ 
    sleep.sleep(10); 
    getMailToSend(function(err, mail) { 
     if(err) //Do log, whatever 
     sendMail(mail, function(err, response) { 
      if(err) //Do log... 
     }); 

    } 

正如你可以閱讀:

  1. 郵件沒有發送一個接一個
  2. 睡眠真的凍結,所以它也凍結sendmail的(哎呀)

是否有人知道誰意識到這一點?後

編輯qubyte

的第一個解決方案,我有一個解決方案,但uggly之一:■

var obj = { sent: true}; 

setInterval(function() { 
    if(obj.sent === false){ 
     return; 
    } 
    obj.sent = false; 
    getMailToSend(function(err, mail) { 
     sendMail(function(err, response){ 
     obj.sent = true; 
     }); 
    }); 
}, 10000); 

回答

1

如果你要問的是一個郵件發送下一個之前完成,那麼像這樣的異步功能可以幫助您解決問題:

function handleMail (callback) { 
    function getMailToSend() { 
     // Logic to get mail. 

     // No mail left to process. 
     if (!mail) { 
      return callback(); 
     } 

     sendMail(mail); 
    } 

    function sendMail(mail) { 
     // Logic to send the mail. 

     getMailToSend(); 
    } 

    // Get the get-send cycle started. 
    getMailToSend(); 
} 

注意,handleMail功能encapsu lates getMailToSendsendMail,它們互相呼叫。需要警告的是,目前的JavaScript對可以經歷的週期數有限制,直到你的調用堆棧變得太大,這是一個堆棧溢出!

最後,編寫這種異步代碼容易導致程序員錯誤。我強烈建議選擇一個庫來爲你做。一個受歡迎的(我喜歡)是async,但有很多選擇。在上述情況下async.whilst可以幫助你。

除了 - 下面的代碼測試中調用堆棧大小:

var i = 0; 

function a(){ 
    i += 1; 
    a(); 
} 

a(); 

給出的Node.js v0.10.26 i = 24275

+0

好吧,它有幫助,但如果getMailToSend比定時器更多,一次有兩個執行或更多...不完全是我想要的: -/ – farvilain

+0

所以你想等到一個發送完成後再開始下一個? – qubyte

+0

是啊,它可能看起來很愚蠢,但真實點在我的背景下做,以解釋。 – farvilain