如何让Node等待promise在无限while循环中完成?

问题描述:

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

我相信你的回调不会被调用的原因是因为你永不放弃的节点运行时有机会这样做。这是一个单一的线程,你可以无限地使用它,你的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