2015-01-20 3 views
0

Я в довольно уникальной ситуации (я никогда не встречался раньше), и я не могу найти ничего о том, как это должно быть обработано, поэтому я подумал, что попрошу здесь. (и, возможно, начните хорошее обсуждение того, как его следует обрабатывать)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 к записи базы данных задним числом. Хотя я могу потенциально использовать инструкцию для этого без полностью изолированных запросов к базе данных, еще не исследовал это.

+0

Я хотел бы помочь с некоторыми Javascript, как говорится в названии. – Catalyst

+1

Вы можете использовать либо, он применяется одинаково хорошо, как и все '=>' в CoffeeScript, это вызов функции и вызов 'call' или' apply' (не помню, какой) в конце и передача 'this'. Хотя хороший момент. Изменил! – TylerFowler

+0

Кроме того, боковая панель, присваивающая 'this' переменной контекста, работает, но опять же не благоприятна, если есть более элегантное решение. – TylerFowler

ответ

0

В JavaScript, если вам необходимо сохранить определенный контекст, его стандартная практика, чтобы использовать переменные себя, как, например:

var self = this; 

В CoffeeScript жир стрелка является стандартной практикой для подобных случаев, хотя использование «я» тоже не так.

+0

Интересно.Это по сути то, что я сделал (использовал только 'ctxt' вместо' self'). Думал, что это может быть по-другому. В этом случае я не могу использовать жирную стрелку, поскольку мне нужны два разных контекста в одном и том же закрытии. Благодаря! – TylerFowler

Смежные вопросы