Я в довольно уникальной ситуации (я никогда не встречался раньше), и я не могу найти ничего о том, как это должно быть обработано, поэтому я подумал, что попрошу здесь. (и, возможно, начните хорошее обсуждение того, как его следует обрабатывать)CoffeeScript Preserve Несколько объектов `this`?
Я пишу приложение Node.js/Express, которое выполняет серию вызовов базы данных в разных обработчиках маршрутов. Я использую модуль node-sqlite3 для вызова базы данных. В этом случае пользователь загружает файл, поэтому я беру это из формы POST-данных и сохраняю их в файловой системе (позже будет перемещен в хранилище blob) и сгенерирует некоторые XML-файлы по другим причинам. Способ, которым я называю эти файлы, - это идентификатор в базе данных для облегчения маршрутов, таких как '/ file /: id', чтобы ПОЛУЧИТЬ файл позже, а также использовать базу данных, чтобы гарантировать, что у меня нет проблем с конфликтами имен.
Я делаю это в CoffeeScript, поэтому я обертываю эту модель в class
, поэтому для доступа к этим вспомогательным методам используется this
(или @
). Прежде чем я сделал вызов last_insert_rowid()
, чтобы получить идентификатор вещи, которую я только что вставил, но это открывает мне возможные условия гонки. Таким образом, когда вы делаете INSERT
в модуле node-sqlite3, обратный вызов, который он вызывает, когда он выполняется, сохраняет последний вставленный идентификатор строки в объекте 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
для доступа к методам экземпляра, но мне также нужно получить значение lastID
из this
объекта, возвращенного по умолчанию из обратного вызова в вызове дб. Очевидно, что если я изменю обратный вызов на вызов db на жирные стрелки, я могу получить доступ к моим методам класса, но затем @.lastID
возвращает undefined
.
Что такое «правильный» способ достичь этого? (в CoffeeScript или JavaScript, не имеет особого значения) Я думаю, что способ, которым я могу это решить, - назначить переменную контекста, например ctxt = @
, но, очевидно, это не выгодно. Есть идеи?
EDIT: О, и я забыл упомянуть, я не могу просто назвать файл чем-то другим, потому что мне также нужен этот идентификатор для обновления базы данных. Вызов async.waterfall
: Сохранить файл -> сгенерировать файл метаданных xml & сохранить его -> добавить путь к файлу xml к записи базы данных задним числом. Хотя я могу потенциально использовать инструкцию для этого без полностью изолированных запросов к базе данных, еще не исследовал это.
Я хотел бы помочь с некоторыми Javascript, как говорится в названии. – Catalyst
Вы можете использовать либо, он применяется одинаково хорошо, как и все '=>' в CoffeeScript, это вызов функции и вызов 'call' или' apply' (не помню, какой) в конце и передача 'this'. Хотя хороший момент. Изменил! – TylerFowler
Кроме того, боковая панель, присваивающая 'this' переменной контекста, работает, но опять же не благоприятна, если есть более элегантное решение. – TylerFowler