【问题标题】:Java Script Promises - If Statement Return Best PracticesJavascript Promises - If 语句返回最佳实践
【发布时间】:2018-12-10 14:22:45
【问题描述】:

我正在编写一个 node.js 函数,它根据条件返回不同的承诺,即 cod:

if(condition){
    return promise.then(() => {
        return Promise.resolve(value)
    })
}else{
    return anotherPromise
}

现在的问题是,如果条件为真,我需要在承诺完成后做一些事情,但在另一种情况下,我只是返回承诺,所以eslint 告诉我嵌套承诺是一种不好的做法.所以这段代码对我不起作用:

(() => {
    if(condition){
        return promise
    }
    }else{
        return anotherPromise
    }
}).then(() => {
    return Promise.resolve(value)
})

因为使用此代码,then 回调将在两种情况下执行。

处理这种情况的最佳做法是什么?

【问题讨论】:

  • 可以切换到async/await 吗?
  • 上面的Promise.resolve(value) 真的是代码的一部分还是只是其他逻辑的占位符?如果它是代码的一部分,那你为什么不直接返回 value 呢?实际上不需要包装这个。
  • 只需编写您需要的任何 js 并将其编译为您的目标所需的任何内容,如果您想使用 typescript,您可以使用任何 javascript 编译器或只使用 typescript 编译器。正如@Sirko 所提到的,async await 作为一种选择可能是最好和最舒适的解决方案。
  • @AmeerTaweel babeljs.io 。如果你想玩一些预设(你需要添加 ES2017 预设),去这里:es6console.com。只需编写您的代码,点击转换并检查它是如何转换的。

标签: javascript node.js promise


【解决方案1】:

一个简单的建议,(这应该可行)在解析的参数中传递条件并在 then 块中检查它。下面的伪代码会更清楚地说明:

(() => {
    if(condition){
        return new Promise((resolve,reject)=>{
            //Some tasks
            resolve(condition)

            //Some reject condition
            reject()
        })
    }
    else {
        return new Promise((resolve,reject)=>{
            //Some tasks
            resolve(condition)

            //Some reject condition
            reject()
        })
    }
}).then((condition) => {
     if(condition) {
         //Do something
     }
     else {
        //Do Nothing
     }
})

【讨论】:

  • 我不确定您的代码解决了什么问题。 Promise 仍然是嵌套的。
  • 专注于你问题的这一部分“现在的问题是,如果条件为真,我需要在承诺完成后做一些事情,但在另一种情况下,我只是返回承诺。”
  • 对不起,我无法理解 Promise 仍然嵌套是什么意思。
  • @RajaNandSharma 你并没有真正改变代码中的任何内容。
【解决方案2】:

eslint 告诉我嵌套 promise 是一种不好的做法。

只需告诉它shut *** up禁用这条语句的linter。 Promise 具有精确嵌套的能力,以便您可以在需要时嵌套它们,这就是其中一种情况。你的代码很好。

【讨论】:

  • 我知道这不会影响代码性能,但我正在尝试使用最佳实践来提高代码的可读性和简洁性。
  • @AmeerTaweel 如果控制流需要嵌套,嵌套没有什么问题。由于这个确切的原因,Promise 被设计为可嵌套的。如果您想要干净(但冗长)的代码,请将内部回调分解为一个额外的命名函数。如果您想要可读的代码,请使用async/await,但在 cmets 中您说您不能这样做。
  • 实际上我想这是为了可读性而创建额外函数的最佳解决方案,我知道代码在嵌套 promise 时会完美运行,但 eslint 一直向我显示烦人的警告,所以我想知道什么是更好的方法。
【解决方案3】:

好像你把它复杂化了。 then 方法已经返回了一个 Promise,所以你不需要在其中放入 Promise.resolve。

为简单起见,您可以这样做

return condition
  ? promise.then(() => value)
  : anotherPromise

【讨论】:

    【解决方案4】:

    如果您使用经典 (ES6 / ES2015+) Promise 语法,则必须将 Promise 链接起来(这没什么不好!)。

    但您也可以选择将代码拆分为函数以获得可读性和avoid nesting issues

    const firstCase = () => ... // returning a promise
    const secondCase = () => ... // returning a promise
    
    if (condition) {
      return firstCase()
    } else {
      return secondCase()
    }
    

    但是对于 ES7/ES2016+,你可以使用 async/await 语法:

    // in a "async" function
    async function main() {
      if (condition) {
        await promise // if you need the promise result, you can assign it
        return value // the result of an async function is always a Promise.
      } else {
        return anotherPromise
      }
    }
    

    或混合使用两种解决方案。

    【讨论】:

    • 其实我猜第一个解决方案使代码更具可读性。 (因为我不能用async/await
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 2010-09-18
    相关资源
    最近更新 更多