我正在努力升级看起来像这样的库(在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 **/
但是,现在配置依赖于我必须从另一个站点请求的设置,因此看起来更像是这样,并且Machine已更新为解析并使用来自外部源的数据。因此,像这样访问机器有效:
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
数据,也无法控制随后何时或将在Machine上调用哪些方法。我确实能够以任何必要的方式修改Machine。
答案 0 :(得分:1)
您可以将远程呼叫拉出到填充config
的功能中。然后,您可以将machine.createMachine config
和getSomething
调用移动到在config
完全填写后调用的回调。
这样,您的machine
无需知道任何有关远程来源或如何解析数据的信息。
答案 1 :(得分:1)
我认为你不应再公开Machine
构造函数了。相反,您应该公开异步工厂函数:
class Machine # not exported
# ...
exports.createMachine = (config, cb) ->
getConfig(config, (err, configData) ->
if err return cb(err)
cb(new Machine(configData))
)
答案 2 :(得分:1)
我不确定我是否已经解决了这个问题。 getSomething()已经是异步的,对吧?所以可能是getSomething()的实现已经延迟并返回执行。
如果,otoh,你没有内部延迟机制,即你以前依赖于另一个库提供的延迟,比如构建器中内置的数据库驱动程序,那么你需要建立自己的延迟机构。
我能想到的最简单的形式,就像我的头脑一样:
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]
简而言之:如果你还不能做到,记住你在日志中尝试做什么,然后回来。之后,当你准备好做这些事情的时候,循环通过日志然后回到你原来的位置,去接你离开的地方。