我正在努力使用JavaScript异步模式来实现这一目标:
我有一个类(我正在使用CoffeeScript),在构造函数中从一些异步调用初始化了一些属性。然后我有一些方法需要这些属性才能工作。以下是我正在尝试做的简化示例:
# Class definition
class window.MyClass
constructor: ->
@attr = ... # loaded with an ajax call or whatever
myMethod: ->
console.log @attr
# User code
c = new MyClass()
c.myMethod() # should console.log the value loaded asynchronously
所以问题是当调用myMethod()
时,异步调用还没有完成。
我知道一些解决方案,但是它们意味着在回调(或带有promises的函数)中移动方法调用。我想避免这种情况,以便能够通过点击处理程序或其他完全不相关的方法调用此方法。
另请注意,我无法在我的方法中移动异步调用,因为我可能会使用该属性的几个方法,并且我不希望在每次调用时加载attr
,但仅限于构造
有什么想法吗?
答案 0 :(得分:0)
我终于找到了办法。不确定它是否非常干净,但它能够满足我的需求。
在异步加载attr
值后,我发送了一个事件MyClassReady
。
在我的构造函数中,我为MyClassReady
添加了第一个将属性ready
设置为true的侦听器。
然后,在myMethod
中,我将代码包装在一个函数中。如果ready
为真,我会调用此函数,否则我将此函数绑定到MyClassReady
事件。
结果如下:
# Class definition
class window.MyClass
constructor: ->
# Async load of `attr`
self = this
loadAttr (val) ->
self.attr = val
window.dispatchEvent new Event 'MyClassReady'
window.addEventListener 'MyClassReady', ->
self.ready = true
myMethod: ->
self = this
callback = ->
console.log self.attr
# If the attrs are already loaded
if @ready
callback()
else
window.addEventListener 'MyClassReady', ->
callback()
# User code
c = new MyClass()
c.myMethod() # this will wait until attr is loaded
我认为将此代码移到库中会很好,但是对于所有self = this
内容来说,它似乎很复杂。
修改:请注意,IE不支持自定义事件...