CoffeeScript 保留多个“this”对象?
CoffeeScript Preserve Multiple `this` objects?
我处于一种相当独特的情况(我以前从未遇到过这种情况),我找不到任何关于如何处理它的信息,所以我想我应该在这里问一下。 (也许可以就如何处理它展开良好的讨论)
我正在编写一个 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()
所以我需要保留 class this
对象来访问实例方法,但我还需要从 this
中获取 lastID
值数据库调用中的回调默认返回的对象。显然,如果我将 db 调用上的回调更改为 fat arrows,我可以访问我的 class 方法,但随后 @.lastID
returns undefined
。
实现此目的的 "proper" 方法是什么? (在 CoffeeScript 或 JavaScript 中并不特别重要)我认为我可以解决这个问题的方法是在方法的顶部分配一个上下文变量,如 ctxt = @
,但显然这不是有利的.有什么想法吗?
编辑:哦,我忘了说,我不能只给文件命名,因为我还需要那个 ID 来更新数据库。对 async.waterfall
的调用执行:保存文件 -> 生成 xml 元数据文件并保存 -> 将 xml 文件的路径追溯添加到数据库条目。尽管我可以在没有完全隔离的数据库调用的情况下使用语句来执行此操作,但尚未对此进行调查。
在JavaScript中,如果您需要保留特定上下文,其标准做法是使用变量 self,例如:
var self = this;
在 CoffeeScript 中,粗箭头是这种情况的标准做法,尽管使用 'self' 也没有错。
我处于一种相当独特的情况(我以前从未遇到过这种情况),我找不到任何关于如何处理它的信息,所以我想我应该在这里问一下。 (也许可以就如何处理它展开良好的讨论)
我正在编写一个 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()
所以我需要保留 class this
对象来访问实例方法,但我还需要从 this
中获取 lastID
值数据库调用中的回调默认返回的对象。显然,如果我将 db 调用上的回调更改为 fat arrows,我可以访问我的 class 方法,但随后 @.lastID
returns undefined
。
实现此目的的 "proper" 方法是什么? (在 CoffeeScript 或 JavaScript 中并不特别重要)我认为我可以解决这个问题的方法是在方法的顶部分配一个上下文变量,如 ctxt = @
,但显然这不是有利的.有什么想法吗?
编辑:哦,我忘了说,我不能只给文件命名,因为我还需要那个 ID 来更新数据库。对 async.waterfall
的调用执行:保存文件 -> 生成 xml 元数据文件并保存 -> 将 xml 文件的路径追溯添加到数据库条目。尽管我可以在没有完全隔离的数据库调用的情况下使用语句来执行此操作,但尚未对此进行调查。
在JavaScript中,如果您需要保留特定上下文,其标准做法是使用变量 self,例如:
var self = this;
在 CoffeeScript 中,粗箭头是这种情况的标准做法,尽管使用 'self' 也没有错。