在我看来,我想:
:coffeescript
Gmap('#canvas').getAddressBounds request.term
在maps.js.coffee中定义为
Gmap = (mapId) ->
getAddressBounds: (address) ->
data = []
$(mapId).gmap3
action: 'getAddress'
address: address
callback: (results) ->
return unless results
data = $.map results, (item) ->
bounds: item.geometry.bounds
data
但这不起作用。首先,存在范围问题。视图中的脚本看不到Gmap函数。如果我将代码直接添加到视图中,Gmap是可见的,但数据始终返回为[]。
答案 0 :(得分:5)
正在发生的事情是您将异步代码视为同步代码。一些调试输出可能会帮助您将其可视化:
Gmap = (mapId) ->
getAddressBounds: (address) ->
data = []
console.log '1: Calling gmap3'
$(mapId).gmap3
action: 'getAddress'
address: address
callback: (results) ->
console.log '3: Callback called'
return unless results
data = $.map results, (item) ->
bounds: item.geometry.bounds
console.log '2: Returning data'
data
当你传递一个回调时,它可以随时被调用。如果在gmap3
函数期间调用它,则在返回之前确实会设置data
。但是gmap3
使用回调来返回结果而不仅仅是返回的原因是该函数是异步的 - 特别是,它在服务器响应您的查询时调用回调。 JavaScript执行事件的方式,这意味着在所有代码执行完毕之后,保证回调 not 。
在JavaScript(或CoffeeScript)中无法将异步函数包装在同步函数中;甚至在调用回调之前运行无限循环也行不通,因为在所有代码执行完毕之前,JS运行时再也不处理服务器响应(甚至用户输入事件)等事件。所以你所能做的就是改变你的功能,使用回调:
Gmap = (mapId) ->
getAddressBounds: (address, cb) ->
$(mapId).gmap3
action: 'getAddress'
address: address
callback: (results) ->
return unless results
cb $.map results, (item) ->
bounds: item.geometry.bounds
然后这样称呼它:
Gmap('#canvas').getAddressBounds request.term, (data) -> console.log data
我在my CoffeeScript book中更多地谈论JS事件模型。此外,John Resig的How JavaScript Timers Work是必读的。异步性需要一些人习惯,但多线程的好处是惊人的。
答案 1 :(得分:2)
变化 Gmap = ... 至 window.Gmap = ....
将解决问题。原因是coffeescript将所有内容包装在一个匿名函数中。如果你想要一个更多功能的完整模块系统,请看这里
https://github.com/jashkenas/coffee-script/wiki/Easy-modules-with-coffeescript