How to transform an asynchronous function into a synchronous one?

5

I have an asynchronous function and would like it to become synchronous, as being asynchronous it is sending the data to the client before even completing the necessary steps, it follows code:

imap.once('ready', function () {
    openInbox(function (err, box) {
        if (err) throw err;
        imap.search(['ALL'], function (err, results) {
            if (err) throw err;
            let arquivo = imap.fetch(results, {bodies: ''});
            arquivo.on('message', function (msg, num) {
                msg.on('body', function (stream, info) {
                    simpleParser(stream)
                        .then(mail => {
                            email = {
                                id: num,
                                remetente: mail.from.text,
                                destinatario: mail.to.text,
                                assunto: mail.subject,
                                texto: mail.text
                            };
                        })
                        .catch(err => {
                        console.log(err)
                        });
                });
                msg.on('end', function () {
                    console.log(num + ' concluído!');
                })
            });
            arquivo.on('error', function (err) {
                console.log('Erro em arquivo.once: ' + err)
            });
            arquivo.on('end', function () {
                console.log('Concluído!')
            })
        })
    })
});
imap.once('error', function (err) {
    console.log('Erro no Imap.once' + err);
});
imap.once('end', function () {
    console.log('Encerrado!');
});
imap.connect();

How to make this function asynchronous ?? What is the correct place to put the response ??

Note: HapiJS Server

    
asked by anonymous 30.08.2017 / 14:35

1 answer

7

Since arquivo.on('message' calls the function N times, 1 per email, then you can create Promises and insert into an array and then when arquivo.on('end' is called you can expect all promises to be ready and use those emails.

The code would look like this:

imap.search(['ALL'], function(err, results) {
    if (err) throw err;
    let arquivo = imap.fetch(results, {
        bodies: ''
    });
    const emails = []; // <--- aqui vais juntando Promises
    arquivo.on('message', function(msg, num) {
        const compilador = new Promise((resolve, reject) => {
            msg.on('body', function(stream, info) {
                simpleParser(stream)
                    .then(mail => {
                        resolve({
                            id: num,
                            remetente: mail.from.text,
                            destinatario: mail.to.text,
                            assunto: mail.subject,
                            texto: mail.text
                        })
                    })
                    .catch(reject);
            });
            msg.on('end', function() {
                console.log(num + ' concluído!');
            })
        });
        emails.push(compilador);
    });
    arquivo.on('error', function(err) {
        console.log('Erro em arquivo.once: ' + err)
    });
    arquivo.on('end', function() {
        Promise.all(emails).then(array => { // <--- aqui vais vai verificar/esperar que todas estão prontas
            console.log(array);
            console.log('Concluído!');
        })
    })
})
    
30.08.2017 / 15:45