【问题标题】:Is it ok to return false, to pass ESLint consistent-return error with asynchronous functions?是否可以返回 false,通过异步函数传递 ESLint 一致返回错误?
【发布时间】:2017-05-19 23:51:22
【问题描述】:

我正在使用 ExpressJS,需要在我的代码上运行和传递 ESLint 规则。有一个规则“consistent-return”,会抛出这样的代码:

function getUsers( req, res, next ){
  if( req.userIds.length === 0 ){
    return next();
  }

  collection.find({"_id": {$in: req.userIds}}, function( err, doc ){
    if( err ){
      return next();
    }

    req.users = doc;
    return next();
  });//find()
}//getUsers()

现在,此代码给出“一致返回”错误。似乎有 2 个可能的更改可以消除此错误,我不确定哪个是正确的。

function getUsers( req, res, next ){
  if( req.userIds.length === 0 ){
    return next();
  }

  collection.find({"_id": {$in: req.userIds}}, function( err, doc ){
    if( err ){
      return next();
    }

    req.users = doc;
    return next();
  });//find()

  return false; // adding return false passes the ESLint error
}//getUsers()

 function getUsers( req, res, next ){
  if( req.userIds.length === 0 ){
    return next();
  }

  // adding return in below line passes the ESLint error.
  return collection.find({"_id": {$in: req.userIds}}, function( err, doc ){
    if( err ){
      return next();
    }

    req.users = doc;
    return next();
  });//find()
}//getUsers()

请告知哪种方法是正确的。谢谢。

【问题讨论】:

    标签: javascript node.js express asynchronous eslint


    【解决方案1】:

    这里的规则指向一个真正的一致性问题:有时您似乎返回了一个值,而有时您却没有。它只起作用,因为返回的值被忽略了。您的return 语句的唯一要点是从执行函数的其余部分分支出来。

    您的代码具有误导性,会损害可读性。

    替换

    if( err ){
      return next();
    }
    

    if( err ){
      next();
      return;
    }
    

    整个不混乱的代码:

    function getUsers( req, res, next ){
        if( req.userIds.length === 0 ){
            next();
            return
        }
        collection.find({"_id": {$in: req.userIds}}, function( err, doc ){
            if( !err ){
                req.users = doc;
            }
            next();
        });//find()
    }//getUsers()
    

    【讨论】:

    • 感谢 Denys 的回复。我正在尝试您的解决方案。但是return next() 我已经在我的所有代码中使用了。它只是可读性较差还是还有其他严重的缺点?
    • 现在我认为除了强迫读者知道返回值被忽略以了解发生了什么之外,没有任何其他缺点。然而,它可能会越来越令人困惑,因为异步性越来越多地由(返回的)promise 处理。
    • 好的。您的代码通过了 ESLint 测试。但这仍然让我感到困惑。对我来说,它应该返回错误,因为我们在 if 块的开头而不是 find() 函数之后有 return 语句,所以我希望它返回一致返回错误。
    • 在 express 中你不会返回错误,如果需要,你传递它:next(err);
    • 此链接 - eslint.org/docs/rules/callback-return 显示使用返回回调(错误)而不是回调(错误)。此外,如果我使用 next(err); return; ESLint 在某些情况下显示无用返回。如果我删除return;,则会引发一致返回错误。
    【解决方案2】:

    让我们稍微分析一下你的代码,去掉一些细节:

    function getUsers( req, res, next ){
    
      if( req.userIds.length === 0 ){
        return next();
      }
    
      collection.find({"_id": {$in: req.userIds}}, function( err, doc ){
        // lotsa code here
      });
    
    }
    

    这里,在函数getUsers() 内,可以有两个代码路径:错误条件(当req.userIds 为空时)或不。

    根据是否满足错误条件,函数getUsers() 要么返回一些东西(next()),要么什么都不返回(实际上隐式返回undefined)。请注意,collection.find() 在第二种情况下执行,它本身可能会在其中返回一些内容,但getUsers() 不会知道。

    现在,作为 ESLint docs 状态,函数可以返回某些内容或不返回任何内容(隐式 undefined),但不能同时返回(这是不一致的行为);否则会抛出 consistent-return 错误。

    因此,要解决该错误,Denys 的代码和您自己的第二个可能的更改都将起作用。在 Denys 的代码中,两个代码路径均不返回任何内容(隐式 undefined),而在您的代码中,它们都返回一些内容。

    【讨论】:

    • 感谢@sayanriju 的解释。很有帮助。
    • 不客气!实际上,我自己最近才开始使用 ESLint,并且遇到了完全相同的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多