【发布时间】: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 中的所有
=>正在做的就是调用函数并在最后调用call或apply(不记得是哪个)并通过this。虽然好点。改了! -
另外,侧边栏,将
this分配给上下文变量确实有效,但如果有更优雅的解决方案,这也是不利的。 -
db.run 函数是否允许您将上下文传递给方法调用?
-
不,它没有。 run方法回调里面的
this其实是一个SQLite Statement对象。什么都不能通过。我只是想知道,一般来说,存在哪些模式可以跟踪这样的上下文。
标签: node.js express sqlite coffeescript