farvilain
farvilain

Reputation: 2562

NodeJS: Async comportment not wanted

I'm trying to write a little daemon that checks if there is a mail to send, do jobs if needed then sleep X seconds.

I'm not so familiar with the asynchrone way of NodeJS. So I'm lost.

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

    }

As you can read:

  1. Mails are not sent one AFTER one
  2. Sleep is really freezing, so it freezes the sendmail too (ARGH)

Does somebody knows who to realized that?

Edit after first solution of qubyte

I have a solution but uggly one :s

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

Upvotes: 0

Views: 45

Answers (1)

qubyte
qubyte

Reputation: 17748

If what you're asking for is for one mail to complete before sending the next, then something like this async function may solve your issue:

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

Note that the handleMail function encapsulates getMailToSend and sendMail, which call each other. Be warned, current JavaScript has a limit to the number of cycles this can go through until your call stack grows too big, which is a stack overflow!

Finally, writing this kind of async code is prone to programmer error. I highly recommend choosing a library to do it for you. A popular one (which I favour) is async, but there are many to choose from. In the case above async.whilst can help you.

Aside - The following code tests call stack size:

var i = 0;

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

a();

Gives i = 24275 in Node.js v0.10.26.

Upvotes: 1

Related Questions