Node.js: Обходной путь для вызова методов, когда объект не завершен инициализация? - PullRequest
0 голосов
/ 03 февраля 2012

Я работаю над обновлением библиотеки, которая выглядит примерно так (для краткости в coffeescript):

//machine.coffee

exports.Machine = class Machine
  constructor: (config) ->
    /** initialize Machine with config data **/

  getSomething: (callback) ->
    /** do something that depends on config **/
    callback null, something     

и используется так, как вы могли ожидать:

machine = require 'machine'
config = {knob: "tweak", switch: "fiddle" }

myMachine = machine.createMachine config

myMachine.getSomething (err, something) ->
  /** we now have something **/

Однако теперь конфигурация зависит от параметра, который я должен запросить с другого сайта, поэтому он выглядит примерно так, и машина была обновлена ​​для анализа и использования данных из внешних источников. Так что доступ к Машине, как это работает:

config = {knob: "tweak", switch: 'http://returns/switch/data' }

/**methods now must wait until Machine is initialized with remote config data **/
machine.createMachine config, (err, machine) ->
  machine.getSomething (err, something) ->
     /** we now have something **/

Но проблема в том, что это нарушает первоначальное использование, которое было:

myMachine = machine.createMachine config

/** remote calls to config not completed yet **/

myMachine.getSomething (err, something) ->
  /** we don't have something because Machine is still initializing **/

Мой вопрос: есть ли способ сохранить исходный вариант использования? Один из подходов может заключаться в том, чтобы ставить вызовы методов неинициализированного класса в очередь до его полной инициализации, но я не уверен, как вообще начать это делать. Есть ли способ поставить в очередь методы? Или есть другие лучшие подходы, которые позволили бы работать устаревшему коду с оригинальным использованием?

Разъяснение : У меня нет контроля над исходными данными config и над тем, когда и какие методы будут впоследствии вызываться на компьютере. У меня есть возможность модифицировать Машину любым необходимым способом.

Ответы [ 3 ]

1 голос
/ 03 февраля 2012

Я не думаю, что вы должны больше выставлять конструктор Machine.Скорее, вы должны предоставить асинхронную фабричную функцию:

class Machine # not exported
    # ...

exports.createMachine = (config, cb) ->
    getConfig(config, (err, configData) ->
        if err return cb(err)

        cb(new Machine(configData))
    )
1 голос
/ 04 февраля 2012

Я не уверен, что понимаю проблему. getSomething () уже асинхронный, верно? Таким образом, по-видимому, реализация getSomething () уже отложена и возвращает выполнение.

Если, ооо, у вас нет внутреннего механизма отсрочки, т.е. вы ранее полагались на отсрочку, предоставляемую другой библиотекой, например драйвером базы данных, который встроен в ваш конструктор, тогда вам нужно будет создать свою собственную отсрочку механизм.

Самая простая форма, которую я могу придумать, с моей головы была бы что-то вроде:

exports.Machine = class Machine
  constructor: (config) ->
    @deferred = []
    initialize (err, @magic) => 
      @ready = true
      def[0].apply( @, def[1] ) for def in @deferred

  getSomething: (callback) ->
    if @ready
      @magic.getSomething (err, stuff) -> callback( stuff )
    else
      @deferred.push [@getSomething, arguments]

В двух словах: если вы еще не можете сделать это, вспомните, что вы пытались сделать в журнале, а затем просто вернитесь. Позже, когда вы будете готовы сделать это, пройдитесь по журналу и вернитесь туда, где вы были, чтобы узнать, где вы остановились.

1 голос
/ 03 февраля 2012

Вы можете извлечь удаленные вызовы в функцию, которая заполняет config. Затем вы можете переместить machine.createMachine config и getSomething вызов в обратный вызов, который вызывается после того, как config полностью заполнен.

Таким образом, вашему machine не нужно ничего знать об удаленных источниках или о том, как анализировать их данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...