关于回调的Coffeescript和Node Js编码风格

时间:2013-08-25 11:45:13

标签: node.js coding-style coffeescript

让我们谈谈这一点。我喜欢CS,我喜欢节点,而且我使用回调就像上帝所建议的那样好。

不幸的是,我通常最终会在稍微嵌套的回调中不断检查错误。

以下是完成相同示例任务的三种不同样式。 哪一个可以用来避免压痕和条件地狱,同时又不牺牲可读性?

如果不使用promises,async或iced-cs,请随时建议新的。

authenticate: (token, cb) =>
  @collection 'services', (err, collection) =>
    if err
      cb err, undefined
    else
      collection.findOne token: token, (errFindingService, service) =>
        if err
          cb errFindingService, undefined
        else
          cb undefined, service

authenticate: (token, cb) =>
  @collection 'services', (err, collection) =>
    if not err
      collection.findOne token: token, (errFindingService, service) =>
        if not errFindingService
          cb undefined, service
        else
          cb errFindingService, undefined
    else
      cb err, undefined

authenticate: (token, cb) =>
  @collection 'services', (err, collection) =>
    return cb err, undefined if err
    collection.findOne token: token, (errFindingService, service) =>
      return cb errFindingService, undefined if err
      cb undefined, service

PS:在第二个我使用if not err而不是unless来符合https://github.com/polarmobile/coffeescript-style-guide

提前谢谢大家。 ^ _ ^

3 个答案:

答案 0 :(得分:3)

我在CoffeeScript中用于错误处理的首选样板是return callback error if error。所以

queryDb conditions, (error, results) ->
  return callback error if error
  console.log result for result in results
  • 这是一个单行程
  • 我强烈希望错误处理始终位于顶部,并使return
  • 将逻辑短路
  • 这会将成功代码保留在相同的缩进级别,而不是if/else

答案 1 :(得分:0)

第一个更接近nodejs在内部使用的内容,例如在fs模块中。

err是第一个参数,因此首先检查它是有意义的。一旦完成它,它就会“深入”回调堆栈。

第一个和第三个选项编译为相同的JS,但显式返回除外。

哪个更易于阅读和识别必备作品?考虑从现在起几个月后查看代码。

来自Python背景,我更喜欢使用更开放的结构(例如第一个),除非更紧凑的形式更清晰。因此,虽然我喜欢Coffeescript理解,但我不太喜欢省略所有可能的{}()的表达式。如果我不得不停下来并精神上补充这些,那么简洁性已经太过分了。

答案 2 :(得分:0)

使用flat-flow,它看起来像这样:

{ flow } = require 'flat-flow' 

authenticate: (token, done) ->
  flow { getCollection: @collection }, [

    # Get collection.
    (done) ->
      @getCollection 'services', (err, collection) ->
        done err, { collection }

    # Get service
    (done) ->
      @collection.findOne { token }, (err, service) ->
        done err, { service }

    # # Get service (alternative)
    # (done, { collection }) ->
    #   collection.findOne { token }, (err, service) ->
    #     done err, { service }

  ], (err, { service }) ->
    done err, service

    # You can use @service as well.

长调用链(有或没有条件)仍然很干净。