Javascript Promise在catch块中解析

时间:2017-03-07 15:54:54

标签: javascript node.js error-handling es6-promise

我有一个函数sendMail,它返回一个promise。

module.exports = function sendMail(mailData) {

const smtpConfig = {
 service: 'gmail',
 auth: {
   user: MAIL_USER,
   pass: MAIL_PASS
 }
};

const trans = nodemailer.createTransport(smtpConfig);

return new Promise((reject, resolve) => {
 trans.sendMail(mailData, (err, result) => {
   if (err) {
     console.log('error', err)
     reject(err);
   }
   else {
     console.log('no error', result)
     resolve(result);
   }
  });
 });
}

承诺解析,记录的输出是:

no error { accepted: [ 'test@test.com' ],
rejected: [],
response: '250 2.0.0 OK 1488900621 j79sm6419250itb.0 - gsmtp',
envelope: { from: '', to: [ 'test@test.com' ] },
messageId: '<511ca80b-0bec-2d06-8f52-81194bcbf26b@My-MacBook-Pro.local>' }

电子邮件已发送。 但是,从另一个模块调用该函数时,结果将作为错误传递给.catch块。

 module.exports = User = {

 sendMail(mailData)
   .then((result) => {
     console.log('here', result)
   })
   .catch((err) => {
     console.log('error', err)
   });

}

产生相同的输出但是作为catch块中的错误:

error { accepted: [ 'test@test.com' ],
rejected: [],
response: '250 2.0.0 OK 1488900621 j79sm6419250itb.0 - gsmtp',
envelope: { from: '', to: [ 'test@test.com' ] },
messageId: '<511ca80b-0bec-2d06-8f52-81194bcbf26b@MY-MacBook-Pro.local>' }

.then块永远不会运行。

非常感谢任何关于我在这里失踪的帮助。

1 个答案:

答案 0 :(得分:3)

下面:

return new Promise((reject, resolve) => {

你混淆了函数参数的顺序。无论您如何命名,您的函数都会先resolve传递,reject秒传递,因此resolve将充当reject,反之亦然。

应该是:

return new Promise((resolve, reject) => {

传递给Promise构造函数的函数的参数名称无关紧要,但顺序很重要。因此,例如,您可以使用它来产生已解决的承诺:

new Promise((x, y) => x(123));
// same as Promise.resolve(123);

或者这产生了被拒绝的承诺:

new Promise((x, y) => y(123));
// same as Promise.reject(123);

但如果您切换xy,那么它会有所不同 - 现在x拒绝:

new Promise((y, x) => x(123));
// same as Promise.reject(123);

y结算:

new Promise((y, x) => y(123));
// same as Promise.resolve(123);

参见文档:

  

语法

new Promise( /* executor */ function(resolve, reject) { ... } );

所以这个谜不是为什么它不起作用,而是为什么它在其他模块中起作用。也许它确实像:

Promise.reject(3).catch(e => e).then(val => console.log('val:', val));

但是当然使用你的函数代替Promise.reject(3)并使用其他逻辑代替console.log