uioporqwerty uioporqwerty - 2 months ago 10
Javascript Question

How to make Node wait for promise to complete in an infinite while loop?

The snoowrap library returns a promise when a function a call is made using it. I would like for node to wait until the call is complete and then execute its callback function. How can I do that? I've tried different forms of using setTimeout, wait.for library, and other solutions but none have worked.

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"
});
}


SOLVED: Here is the solution below that worked for me based on the code in the accepted answer:

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"
});
}

Answer

I believe the reason your callback never gets called is because you never give the node runtime a chance to do that. It's a single thread and you are infinitely using it up with your while(1). It will not have a chance to actually handle the resolving network call that the promise responds to as you are keeping the thread busy with more

As mentioned in the comment: In node, you shouldn't block the rest of the server on a callback. Instead, you should make sendToSlack a recursive function that deals with the callback and fires off another call to reddit.getHot() and get rid of the loop

Conceptual code:

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);

Just off hand code

Comments