2016-10-01 123 views
-1

snoowrap庫在函數調用時使用它返回一個promise。我希望節點等待,直到調用完成,然後執行其回調函數。我怎樣才能做到這一點?我嘗試過使用setTimeout,wait.for庫和其他解決方案的不同形式,但都沒有奏效。如何讓Node等待promise在無限while循環中完成?

 while(1){ 
      for (var i = 0; i < allowableTimes.length; i++) { 
       if (new Date().getTime() == allowableTimes[i].getTime()) { 
        reddit.getHot('aww', {limit: 1}).then(sendToSlack); 
       } 
      } 
     } 

function sendToSlack(res){ 
    var url = res[0].url; 
    var title = res[0].title; 

    bot.sendWebhook({ 
     username: "bawwt", 
     icon_emoji: ":smile_cat:", 
     text: "<" + url + "|" + title + ">", 
     channel: "#random" 
    }); 
} 

解決:這裏是低於該解決方案基於接受的答案代碼爲我工作:

if (!err) { 
      reddit.getHot('aww', {limit: 1}).then(handleReddit); 
    } 
}); 

function handleReddit(res) { 
    for (var i = 0; i < allowableTimes.length; i++) { 
     if (validTime(allowableTimes[i])) { 
      sendToSlack(res); 
     } 
    } 
     queryReddit(); 
} 

function validTime(allowableTime) { 
    var date = new Date(); 

    var hour = date.getHours(); 
    var minute = date.getMinutes(); 

    var allowableHour = allowableTime.getHours(); 
    var allowableMinute = allowableTime.getMinutes(); 

    return hour == allowableHour && minute == allowableMinute; 
} 

function queryReddit() { 
    setTimeout(function() {reddit.getHot('aww', {limit: 1}).then(handleReddit);}, 60000); 
} 

function sendToSlack(res){ 
      var url = res[0].url; 
      var title = res[0].title; 

      bot.sendWebhook({ 
       username: "bawwt", 
       icon_emoji: ":smile_cat:", 
       text: "<" + url + "|" + title + ">", 
       channel: "#random" 
      }); 
} 
+0

假設你的意思是'reddit.getHot()'調用。你確定要等待電話完成嗎?我想這就是'sendToSlack'回調的用途。在節點中,您不應該在回調中阻塞服務器的其餘部分。 相反,您應該使'sendToSlack'成爲一個遞歸函數,處理回調並觸發'reddit.getHot()'的另一個調用並擺脫循環 – Monokh

+0

sendToSlack函數使用reddit.getHot函數的結果,但函數永遠不會完成,並且節點似乎很快就會循環。如果有幫助,我會添加sendToSlack的內容。 – uioporqwerty

回答

1

我相信你的回調不會被調用的原因是因爲你永不放棄的節點運行時有機會這樣做。這是一個單一的線程,你可以無限地使用它,你的while(1)。它不會有機會實際處理承諾響應的解決網絡調用,因爲您保持線程忙碌更多

正如評論中所述:在節點中,您不應該阻塞服務器的其餘部分在回調中。相反,你應該讓sendToSlack遞歸函數與回調和火災關閉另一呼叫reddit.getHot(交易),擺脫循環的

概念代碼:

var allowableTimes = 20; 
var times = 0; 
function handleReddit(res) 
{ 
    sendToSlack(res); 
    times = times + 1; 
    if(times < allowableTimes) 
    { 
     reddit.getHot('aww', {limit: 1}).then(handleReddit); 
    } 
} 

reddit.getHot('aww', {limit: 1}).then(handleReddit); 

剛剛送走手代碼

+0

這不會導致我達到reddit api的速率限制,如果allowableTimes足夠高,它會達到最大函數調用堆棧大小? – uioporqwerty

+0

@uioporqwerty這是一個單獨的問題,它取決於你。如果您想限制速度,請稍等。如果您的'allowableTimes'數量較少,我個人並不認爲這樣做會出現問題,這看起來像您在這種情況下應該有的。如果你打算運行比調用堆棧最大的時間更多(這種方式可笑地高)。然後,您可以通過超時功能重置堆棧大小。 – Monokh

+0

@uioporqwerty 另外我不相信,在這種情況下,無論有多高的允許時間,這都會發生。方法調用不會進入堆棧。 'reddit.getHot'接受一個回調,所以它應該是下一次調用產生的新堆棧。如果'reddit.getHot()'同步發生,那麼這將是一個問題 – Monokh