2017-08-11 49 views
0

这是我在一个节点中的代码 - 表示一旦sql事务成功完成就发送一封电子邮件!节点回调 - 代码不能正常工作

router.post('/',function(req,res,next){ 
    sql.connect(config).then(function() { 
     var request = new sql.Request(); 
     request.query(`update projects set CIP_NCIP= '${req.body.cip_noncip}' , Capital_Expense ='${req.body.capital_expensed}' , Approval_Status ='Approved' where Project_ID ='${req.body.projid}'`).then(function(recordset) { 
      console.log('Recordset: ' + recordset); 
      console.log('Affected: ' + request.rowsAffected); 
     }).catch(function(err) { 
      if(err) { 
       console.log('Request error: ' + err); 
      } 
     }) 
    }).then(
     transporter.sendMail(mailOptions, function(error, info){ 
      if (error) { 
       console.log(error); 
      } else { 
       console.log('Email sent: ' + info.response); 
      } 
     })).catch(function(err) { 
     if (err) { 
      console.log('SQL Connection Error: ' + err); 
     } 

    }); 
}); 

SQL插入似乎工作,但它不是执行的代码

transporter.sendMail(mailOptions, function(error, info){ 
       if (error) { 
        console.log(error); 
       } else { 
        console.log('Email sent: ' + info.response); 
       } 
      }) 

相当新的回调和ES5该位。建议表示欢迎

+0

的问题,我可以看到,但只要代码执行,它看起来likt它应该工作的夫妇 - 如果移动'的Sendmail调用'request.query'的回调函数可以在那里正常工作吗?还有'mailOptions'从哪里来?在代码中没有看到,我们是否假设这存在并且配置正确? – James

+0

这是整个js文件https://www.itextpad.com/nXB8DStC2s – SSS

+0

甚至在request.query回调中的console.log('test')也不起作用,这很令人困惑。 – SSS

回答

2

根据你当前的代码,你没有以正确的顺序(这可能是也可能不是问题)做实际的事情。试试这个:

var request = sql.Request(); 
sql.connect(config) 
    .then(function() { 
     console.log('UPDATING RECORD...'); 
     return request.query(`update projects set CIP_NCIP= '${req.body.cip_noncip}' , Capital_Expense ='${req.body.capital_expensed}' , Approval_Status ='Approved' where Project_ID ='${req.body.projid}'`); 
    }) 
    .catch(function(err) { 
     if (err) { 
      console.log(`SQL Connection Error: ${err}`); 
     } 
    }) 
    .then(function(recordset) { 
     console.log('Recordset: ' + recordset); 
     console.log('Affected: ' + request.rowsAffected); 
     console.log('SENDING EMAIL...'); 
     return transporter.sendMail(mailOptions); 
    }) 
    .catch(function(err) { 
     if (err) { 
      console.log(`Nodemailer Err: ${err}`); 
     } 
    }) 
    .then(function() { 
     console.log('COMPLETE'); 
    });   
    console.log('CONNECTING...'); 

以上是利用承诺的最大范围内,包括一些记录,应该帮助你缩小那里的问题。这里

FWIW是它会怎样看在ES6(不调试日志记录)

sql.connect(config) 
    .then(() => sql.Request().query('...')) 
    .catch(err => console.error(`SQL Error ${err}`)) 
    .then(() => transporter.sendMail(mailOptions)) 
    .catch(err => console.error(`Nodemailer err: ${err}`); 
+0

实现此作品! – SSS

+0

@SSS很酷,你应该考虑升级到ES6,你的代码会更加简洁(我用一个例子更新了我的答案)。 – James

+0

可能是我应该的。你会推荐任何有趣的教程? – SSS

0

看起来你忘了通过执行您提供通过.then方法连接功能原样

return request.query(`update projects set CIP_NCIP= '${req.body.cip_noncip}' , Capital_Expense ='${req.body.capital_expensed}' , Approval_Status ='Approved' where Project_ID ='${req.body.projid}'`).then(function(recordset) { 
      console.log('Recordset: ' + recordset); 
      console.log('Affected: ' + request.rowsAffected); 
     }).catch(function(err) { 
      if(err) { 
       console.log('Request error: ' + err); 
      } 
     }) 
+0

你没有_have_返回承诺连锁。 – James

2

一个承诺如下承诺链返回承诺。

在你的情况有:

sql.connect(config) 
    .then(function() { ... }) 
    .then(valueNotAFunction); 

如果then执行的函数的返回值是一个承诺本身,那么接下来的块等待完成前一个。

的代码块:

transporter.sendMail(mailOptions, function(error, info){ 
    if (error) { 
     console.log(error); 
    } else { 
     console.log('Email sent: ' + info.response); 
    } 
})) 

立即执行,而不是之后在链上一功能已完成。

此外request.query评估为承诺,你不回到链。

您的代码应该是这样的:

sql.connect(config) 
    .then(function() { .... ; return request.query(...) }) 
    .then(function() { .... ; return transporter.sendMail(....) }) 
    .catch(function(error) { console.error(error); }); 

记住transporter.sendMail可能不计算的承诺,所以你可能要与some promisification library把它包起来。

+0

所以我也注意到了这一点,但是它并不能解释代码为什么不能运行。如果有的话,它只是意味着电子邮件会在数据库更新之前触发。 – James

+0

最有可能的'运输车。sendMail'使它的连接被初始化,这就是为什么不立即发送邮件。没有办法猜测那里发生了什么,而不知道'transporter.sendMail'在做什么。 – drinchev

+1

基于代码,我的猜测是OP正在使用[nodemailer](https://nodemailer.com/about/)哪个_can_返回一个Promise。但是,我注意到OP正在提供一个回调,所以不会在他们的情况下。 – James