【问题标题】:Promise chaining and conditionals承诺链和条件
【发布时间】:2021-08-01 09:50:18
【问题描述】:

很确定我可以使用 async/await 来做到这一点,但我想了解如何在没有的情况下实现此逻辑。

工作流程:

  • 在数据库中找工作
  • 如果job存在,找Person,如果不存在,给前端发响应
  • 然后做人的逻辑

代码:

    Job.findByPk(jobId)
       .then(job => {
           if(job) return Person.findOne(...)
           else res.status(404).json(...)
       })
       .then(person => {
           if(person)
               // Do person logic here
       })
       .catch(err => ...);

问题是这个逻辑显然行不通。如果找不到工作找不到人,则第二个.then() 块中的person 参数可能未定义。

所以解决方案是在第一个 .then() 块中执行此操作:

       .then(job => {
           if(job) // store the job locally
           else res.status(404).json(...)

           return Person.findOne(...)
       })

但这意味着无论是否找到工作都会搜索数据库,而不是以找到工作为条件

如何以更有意义的方式构建它?

谢谢

【问题讨论】:

  • 尼克,你不应该在stackoverflow上回答你的问题。这里的问题仅供提问。如果您想显示自己的答案,实际上可以在答案中显示。
  • 对不起,马上改!

标签: javascript node.js express promise


【解决方案1】:

使用await 会简单得多(假设您创建了父函数async):

try {
    const job = await Job.findByPk(jobId);
    if (!job) {
         return res.status(404).json(...)
    }
    const person = await Person.findOne(...);
    if (person) {
        ...
    } else {
        ...
    }
} catch(e) {
    console.log(e);
    res.sendStatus(500);
}

使这个流程变得如此简单的原因是所有变量都在同一个范围内,您可以在任何想要完成流程的地方return

如果您要坚持使用之前的 .then() 逻辑,请查看以下答案:How to chain and share prior results with promises 以获得多个不同的选项。

【讨论】:

  • 实际上,在阅读了该链接后,我确实决定打破承诺链。所以我测试了if(!job) throw new Error(...)(我实际上也添加了statusCodes等),并对响应进行错误处理。所以不确定这个问题是否应该重新标记为重复。感谢您的帮助!
【解决方案2】:

您只需在第一个 .then 中添加 .thens。

Job.findByPk(jobId)
  .then(job => {
    if(job)
      return Person.findOne(...)
        .then(person => {
          if(person)
          // Do person logic here
        });
    else res.status(404).json(...)
  })
  .catch(err => ...);

【讨论】:

  • 是的,不过,我试图不嵌套任何东西。没有别的原因,我知道这是可能的,并且想学习如何做。答案是打破承诺链。不过感谢您的回答!
  • @NickW 不嵌套是一个非常好的规则。避免嵌套的一种简单方法是将嵌套逻辑放入它自己的函数中。
【解决方案3】:

选择的答案是实现我想要的最佳方式 - 即只使用 async/await - 但对于任何想知道我如何坚持使用链接的人来说,它只是正确地打破它。我最终通过抛出一个错误来做到这一点(然后在其他地方处理)

       .then(job => {
           if(!job) {
              const error = new Error('Job not found');
              error.statusCode(404);
              throw error;
           } else  {
              return Person.findOne(...)
           }

       })
       .then(person => { // Person logic })
       .catch(err => next(err))

【讨论】:

    猜你喜欢
    • 2018-02-25
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    • 2016-01-07
    相关资源
    最近更新 更多