JavaScript-expressjs:chain承诺返回关键字时不工作/停止;

JavaScript-expressjs:chain承诺返回关键字时不工作/停止;,javascript,express,sequelize.js,Javascript,Express,Sequelize.js,我的express应用程序中有一个实用程序功能。基本上,我想在特定条件下继续或终止承诺,然后链。但是当我想通过使用return语句来结束这个链时,express说它不能在发送头之后设置头。以下是我所拥有的: function submit_reset_password_request(request, response) { if(request.session.id) { return response.json({ error: true, message: 'password

我的express应用程序中有一个实用程序功能。基本上,我想在特定条件下继续或终止承诺
,然后
链。但是当我想通过使用
return
语句来结束这个链时,express说它不能在发送头之后设置头。以下是我所拥有的:

function submit_reset_password_request(request, response) {
  if(request.session.id) {
    return response.json({ error: true, message: 'password reset cannot be requested during an sctive session' });
  }

  let { email } = request.body;
  let user, reset_request;
  if(email) {
    email = email.toLowerCase().trim();
  }
  if(!email) {
    return response.json({ error: true, message: 'input is required' });
  }

  models.Users.findOne({ where: { email } })
  .then(user_result => {
    if(!user_result) {
      return response.json({ error: true, message: 'No account found by that email' });
    }
    user = user_result.dataValues;
    return models.ResetPasswordRequests.findOne({ where: { user_email: user.email } })
  })
  .then(request_result => {
    if(request_result) {
      return response.json({ error: true, message: 'A password reset has already been requested for this email' });
    }
    return models.ResetPasswordRequests.create({ user_email: user.email })
  })
  .then(new_reset_request => {
    reset_request = new_reset_request.dataValues;

    // send reset request email
    let host = request.get('host');
    let link = host.endsWith('/') ? (host + 'search') : (host + '/search');
    let email_subject = 'Epsity - Password reset requested';
    let email_html = templateEngine.PasswordReset_EMAIL({ user, reset_request, link });
    return sendgrid_manager.send_email(null, request.session.you.email, email_subject, email_html);
  })
  .then(email_result => {
    return response.json({ success: true, message: 'A password reset request has been sent to the provided email!' });
  })
  .catch(error => {
    console.log(error);
    return response.json({ error, message: 'Could not sumbit reset password request...' });
  });
}
每个
链都在查看数据库。当if为false时,
if
语句应该停止链并发送响应并继续,但它仍然继续运行(节点:我仍然在客户端看到响应)。我不知道为什么

以下是错误:

Unhandled rejection Error: Can't set headers after they are sent.
    at validateHeader (_http_outgoing.js:494:11)
    at ServerResponse.setHeader (_http_outgoing.js:501:3)
    at ServerResponse.header (C:\Users\Waite-Ryan-M\Desktop\_my-apps\rmw-epsity\node_modules\express\lib\response.js:767:10)
    at ServerResponse.send (C:\Users\Waite-Ryan-M\Desktop\_my-apps\rmw-epsity\node_modules\express\lib\response.js:170:12)
    at ServerResponse.json (C:\Users\Waite-Ryan-M\Desktop\_my-apps\rmw-epsity\node_modules\express\lib\response.js:267:15)
    at models.Users.findOne.then.then.then.then.catch.error (C:\Users\Waite-Ryan-M\Desktop\_my-apps\rmw-epsity\server\routers\main\methods\post.js:221:21)
    at tryCatcher (C:\Users\Waite-Ryan-M\Desktop\_my-apps\rmw-epsity\node_modules\bluebird\js\release\util.js:16:23)
    at Promise._settlePromiseFromHandler (C:\Users\Waite-Ryan-M\Desktop\_my-apps\rmw-epsity\node_modules\bluebird\js\release\promise.js:512:31)
    at Promise._settlePromise (C:\Users\Waite-Ryan-M\Desktop\_my-apps\rmw-epsity\node_modules\bluebird\js\release\promise.js:569:18)
    at Promise._settlePromise0 (C:\Users\Waite-Ryan-M\Desktop\_my-apps\rmw-epsity\node_modules\bluebird\js\release\promise.js:614:10)
    at Promise._settlePromises (C:\Users\Waite-Ryan-M\Desktop\_my-apps\rmw-epsity\node_modules\bluebird\js\release\promise.js:690:18)
    at _drainQueueStep (C:\Users\Waite-Ryan-M\Desktop\_my-apps\rmw-epsity\node_modules\bluebird\js\release\async.js:138:12)
    at _drainQueue (C:\Users\Waite-Ryan-M\Desktop\_my-apps\rmw-epsity\node_modules\bluebird\js\release\async.js:131:9)
    at Async._drainQueues (C:\Users\Waite-Ryan-M\Desktop\_my-apps\rmw-epsity\node_modules\bluebird\js\release\async.js:147:5)
    at Immediate.Async.drainQueues (C:\Users\Waite-Ryan-M\Desktop\_my-apps\rmw-epsity\node_modules\bluebird\js\release\async.js:17:14)
    at runCallback (timers.js:789:20)
    at tryOnImmediate (timers.js:751:5)
    at processImmediate [as _immediateCallback] (timers.js:722:5)

也许我会尝试
async/await
语法。

问题是,当在
中时,
承诺链中,
承诺
不一定关心您返回的是什么。在你的

.then(user_result => {
  if(!user_result) {
    return response.json({ error: true, message: 'No account found by that email' });
  }
  user = user_result.dataValues;
  return models.ResetPasswordRequests.findOne({ where: { user_email: user.email } })
})
Interpeter将处理
返回响应.json
返回模型相同。重置…
-它将简单地传递到下一个
。然后
,等待承诺解析表达式是否为
承诺。正如你所看到的,它并没有从链条中挣脱出来。将函数提取到可以基于控制流调用的命名函数中(这有点冗长),或者使用
async
/
await
,这与您现在所做的非常类似-使用
async
/
await
return
将终止函数,要获取异步调用的值,请使用
wait
(而不是
return
ing,以便下一个
。然后
可以处理它)

像这样:

async function submit_reset_password_request (request, response) {
  if(request.session.id) {
    return response.json({ error: true, message: 'password reset cannot be requested during an sctive session' });
  }
  const { email } = request.body;
  if(email) {
    email = email.toLowerCase().trim();
  }
  if(!email) {
    return response.json({ error: true, message: 'input is required' });
  }

  try {
    const user_result = await models.Users.findOne({ where: { email } });
    if(!user_result) {
      return response.json({ error: true, message: 'No account found by that email' });
    }
    const user = user_result.dataValues;
    const request_result = await models.ResetPasswordRequests.findOne({ where: { user_email: user.email } });
    if(request_result) {
      return response.json({ error: true, message: 'A password reset has already been requested for this email' });
    }
    const new_reset_request = await models.ResetPasswordRequests.create({ user_email: user.email });
    const reset_request = new_reset_request.dataValues;

    // send reset request email
    const host = request.get('host');
    const link = host.endsWith('/') ? (host + 'search') : (host + '/search');
    const email_subject = 'Epsity - Password reset requested';
    const email_html = templateEngine.PasswordReset_EMAIL({ user, reset_request, link });
    const email_result = await sendgrid_manager.send_email(null, request.session.you.email, email_subject, email_html);
    return response.json({ success: true, message: 'A password reset request has been sent to the provided email!' });
  } catch(error) {
    console.log(error);
    return response.json({ error, message: 'Could not sumbit reset password request...' });
  }
}

谢谢这就是路!