【问题标题】:How to define a callback function with Coffeescript and Rails 3.1?如何使用 Coffeescript 和 Rails 3.1 定义回调函数?
【发布时间】:2023-03-28 07:55:01
【问题描述】:

在我看来我想要:

: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 是可见的,但数据总是以 [] 形式返回。

【问题讨论】:

标签: coffeescript ruby-on-rails-3.1


【解决方案1】:

发生的情况是,您将异步代码视为同步代码。一些调试输出可能会帮助您将其可视化:

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 执行事件的方式,这意味着您的回调保证不会在所有代码执行完毕之前被调用。

在 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 是必读的。异步需要一些时间来适应,但多线程的好处是惊人的。

【讨论】:

    【解决方案2】:

    改变 地图= ... 到 window.Gmap = ....

    将解决问题。原因是咖啡脚本将所有内容都包装在一个匿名函数中。如果您想要更多功能的全模块系统,请看这里

    https://github.com/jashkenas/coffee-script/wiki/Easy-modules-with-coffeescript

    【讨论】:

    • 这解决了范围问题,但没有解决[] 被返回的问题。
    • 你说得对,我只看到了最明显的问题。可惜 StackOverflow 不会让 OP 选择两个答案;)
    猜你喜欢
    • 2020-09-22
    • 2011-12-20
    • 2011-11-08
    • 1970-01-01
    • 2011-09-01
    • 2012-01-30
    • 2012-02-07
    • 2011-10-13
    • 2011-08-31
    相关资源
    最近更新 更多