【问题标题】:Having multiple async awaits inside a promise在一个 Promise 中有多个异步等待
【发布时间】:2018-02-05 22:12:20
【问题描述】:

不确定我是否正确执行此操作。所以我在我的 nodejs 脚本中使用异步等待,我从电子邮件帐户获取电子邮件并将电子邮件和收件人保存到数据库中。我遇到的问题是他们的收件人没有保存最后一封电子邮件。不知道我在这里做错了什么。这是我的代码。

function saveEmailRecipients(message, pool, emailId){
    return new Promise(function(resolve, reject){
            var saveCC =  async function(){
                 //Store cc
                 if(message.cc != undefined){
                    for (var k in message.cc) {
                        let cc = message.cc[k];

                        var request = pool.request();
                        request.input('email_id', sql.Int, emailId);
                        request.input('email_address', sql.VarChar, cc.address );
                        request.input('email_address_name', sql.VarChar, cc.name);
                        request.input('created_by', sql.VarChar, 'system');
                        request.input('recipient_type', sql.VarChar, 'CC');

                        await request.query('INSERT INTO email_recipient_temp(email_id, email_address, email_address_name, created_by, recipient_type) values (@email_id, @email_address, @email_address_name, @created_by, @recipient_type)');


                    }
                }

                 //Store to
                 if(message.to != undefined){
                    for (var j in message.to) {
                        let to = message.to[j];

                        var request = pool.request();
                        request.input('email_id', sql.Int, emailId);
                        request.input('email_address', sql.VarChar, to.address );
                        request.input('email_address_name', sql.VarChar, to.name);
                        request.input('created_by', sql.VarChar, 'system');
                        request.input('recipient_type', sql.VarChar, 'TO');

                        await request.query('INSERT INTO email_recipient_temp(email_id, email_address, email_address_name, created_by, recipient_type) values (@email_id, @email_address, @email_address_name, @created_by, @recipient_type)');
                    }
                }
            }

            var recipientResults = saveCC();
            recipientResults
            .then(function(){
                resolve();
            })
            .catch(function(err){
                reject(err)
            })
        });  
};

async function main() {
    try
    {
        let pool = (await sql.connect(config));

        var messages = (await getEmailsFromEmailServer());

        for (var messageIndex in messages) {

             //Save email
             var emailId =  (await saveEmail(pool,  messages[messageIndex]));
             (await saveEmailRecipients (messages[messageIndex], pool, emailId));
             //(await saveAttachments(messages[messageIndex], emailId));
        }

        client.quit();
        process.exit();
    }
    catch(err){
        console.log(err);
        client.quit();
        process.exit();
    }
};

main();

我省略了一些函数,因此我们可以专注于 saveEmailRecipient。我怀疑我在那里是不对的。我有两个循环,每个循环都在向数据库中插入。我知道request.query 会返回一个承诺。我不确定我是否需要将整个事情包装在另一个异步函数中,或者我应该在这里使用 promise.all。

【问题讨论】:

标签: javascript node.js async-await es6-promise


【解决方案1】:

我猜测保存问题的根源在于您使用的是“process.exit()”而不是正确关闭连接,不幸的是这只是一个假设,因为我无法测试您的代码.

我能否建议您不要在代码中使用 'process.exit' 并使用 Promise 或 async/await。

注意:可以一起使用,只是坑坑比较多,详情见'Understand promises before you start using async/await' by 'Daniel Brain'

这是一个仅使用 Promise 的示例:

function addRecipient(pool, type, id, cc) {
    const request = pool.request();

    request.input('email_id', sql.Int, id);
    request.input('email_address', sql.VarChar, cc.address );
    request.input('email_address_name', sql.VarChar, cc.name);
    request.input('created_by', sql.VarChar, 'system');
    request.input('recipient_type', sql.VarChar, type);

    // Return the query's promise.
    return request.query(`
        INSERT INTO email_recipient_temp (
            email_id,
            email_address,
            email_address_name,
            created_by,
            recipient_type
        ) values (
            @email_id,
            @email_address,
            @email_address_name,
            @created_by,
            @recipient_type
        )
    `);
}
function saveEmailRecipients (message, pool, emailId) {
    // The arrays of promises
    const promises = [];

    // Process the 'TO's
    if(message.to != undefined){
        for (const to of message.to) {
            // Add the promise to the promise array
            promises.push(addRecipient(
                pool,
                'TO',
                emailId,
                to
            ));
        }
    }

    // Process the 'CC's
    if(message.cc != undefined){
        for (const cc of message.cc) {
            // Add the promise to the promise array
            promises.push(addRecipient(
                pool,
                'CC',
                emailId,
                cc
            ));
        }
    }

    // return a promise of promises
    return Promise.all(promises);
}

sql.connect(config)
.then(pool => {
    // Retrieve the messages
    getEmailsFromEmailServer()

    // Convert all the messages into promises
    .then(messages => Promise.all(
        // For each of the messages
        messages.map(message => 

            // Save the email
            saveEmail(pool, message)

            // Now use the emailId (returns a promise)
            .then(emailId => saveEmailRecipients(
                message,
                pool,
                emailId
            ))
        )
    ))

    .catch(err => {
        // There was an error.
        console.error(err);
    })

    // This is run regardless of the promise outcome
    .finally(() => {
        // Tidy up.
        client.quit();
        pool.close();
    });

})

请注意,我不能说这会立即生效,因为我必须做出一些假设,并且无法访问数据库,但是,我希望它会有所帮助。

【讨论】:

  • 我猜你的意思是 addRecipient 而不是 request.query 在 saveEmailRecipients 。你说的对。我的程序退出得太早了。 finally 块的使用是退出程序的更好方法。我喜欢使用 promise.all,因为现在我不需要等待每个数据库完成。谢谢。这是我想做的,但不知道怎么做。
猜你喜欢
  • 2017-01-15
  • 2017-02-10
  • 1970-01-01
  • 1970-01-01
  • 2020-03-04
  • 1970-01-01
  • 1970-01-01
  • 2018-12-31
  • 1970-01-01
相关资源
最近更新 更多