【问题标题】:CoffeeScript Preserve Multiple `this` objects?CoffeeScript 保留多个“this”对象?
【发布时间】:2015-03-19 08:59:57
【问题描述】:

我处于一种相当独特的情况(我以前从未遇到过这种情况),我找不到任何关于如何处理它的信息,所以我想我会在这里问。 (也许就应该如何处理开始一个很好的讨论)

我正在编写一个 Node.js/Express 应用程序,它在各种路由处理程序中执行一系列数据库调用。我正在使用node-sqlite3 模块进行数据库调用。在这种情况下,用户正在上传一个文件,所以我从表单 POST 数据中获取它并将其保存到文件系统(稍后将移动到 blob 存储)并出于其他原因生成一些 xml 文件。我命名这些文件的方式是通过数据库中的 id 来方便以后获取文件的路径,例如“/file/:id”,并利用数据库来确保我没有名称冲突问题。

我在 CoffeeScript 中执行此操作,因此我将此模型包装在 class 中,因此它使用 this(或 @)来访问这些辅助方法。在我进行last_insert_rowid() 调用以获取我刚刚插入的东西的ID 之前,但这让我面临潜在的竞争条件。因此,当您在 node-sqlite3 模块中执行 INSERT 时,它在完成时调用的回调将最后插入的行 ID 保存在 this 对象中(所以 (err) -> fileid = @.lastID)。现在是一些代码(名称已更改和简化)。

uploadFile: (fileData, cb) ->
  @.openConnectionIfClosed()
  @db.serialize =>
    # preserve the @ object to allow calls to class methods like @.saveFile
    @db.run 'insert into thing (val=$val)', $val: 'some_val', (err) ->
      if err
        cb err
        return

      # @ refers to the this object provided by @db.run
      fileid = @.lastID

      async.waterfall [
        (async_cb) =>
          # uh oh, the @ object is the one from the db library, not my class
          # earning me a 'method undefined' error
          @.saveFile fileid, async_cb 
        # etc... you get the idea
        ...
      ], (err) -> cb err
  @.closeConnection()

所以我需要保留类this 对象来访问实例方法,但我还需要从db 调用中的回调默认返回的this 对象中获取lastID 值。显然,如果我将 db 调用上的回调更改为胖箭头,我可以访问我的类方法,但是 @.lastID 返回 undefined

实现这一目标的“正确”方法是什么? (在 CoffeeScript 或 JavaScript 中,并不特别重要)我认为我可以解决这个问题的方法是在方法的顶部分配一个像 ctxt = @ 这样的上下文变量,但这显然是不利的。有什么想法吗?

编辑:哦,我忘了说,我不能只是为文件命名,因为我还需要那个 id 来更新数据库。对async.waterfall 的调用是:保存文件-> 生成xml 元数据文件并保存它-> 将xml 文件的路径添加到数据库条目中。虽然我可能会使用一个语句来执行此操作而无需完全隔离的数据库调用,但尚未对此进行调查。

【问题讨论】:

  • 我很乐意帮助一些 Javascript,就像标题中所说的那样。
  • 你可以使用任何一个,它同样适用于 CoffeeScript 中的所有 => 正在做的就是调用函数并在最后调用 callapply(不记得是哪个)并通过this。虽然好点。改了!
  • 另外,侧边栏,将this 分配给上下文变量确实有效,但如果有更优雅的解决方案,这也是不利的。
  • db.run 函数是否允许您将上下文传递给方法调用?
  • 不,它没有。 run方法回调里面的this其实是一个SQLite Statement对象。什么都不能通过。我只是想知道,一般来说,存在哪些模式可以跟踪这样的上下文。

标签: node.js express sqlite coffeescript


【解决方案1】:

在 JavaScript 中,如果需要保留特定上下文,其标准做法是使用变量 self,如下所示:

var self = this;

在 CoffeeScript 中,粗箭头是此类情况的标准做法,尽管使用 'self' 也没有错。

【讨论】:

  • 有趣。这基本上就是我所做的(仅使用ctxt 而不是self)。想可能有不同的方法。在这种情况下,我不能使用胖箭头,因为我需要在同一个闭包中使用两个不同的上下文。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-18
  • 2018-02-18
  • 2011-02-12
  • 2017-08-26
  • 2014-08-06
  • 2015-11-03
  • 2016-07-08
相关资源
最近更新 更多