2017-08-11 45 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