2011-07-26 2 views
3

は私がしたい:maps.js.coffeeで定義されているCoffeescriptとRails 3.1でコールバック関数を定義する方法は?私の見解で

:coffeescript 
    Gmap('#canvas').getAddressBounds request.term 

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

あなたが説明している範囲の問題は、StackOverflowに関する最も一般的なCoffeeScript質問になっています。 http://stackoverflow.com/questions/6089992/cant-find-variable-error-with-rails-3-1-and-coffeescriptおよびその他の記事を参照してください。 –

答えて

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がイベントを行う方法は、すべてのコードの実行が終了するまで、ではなくがコールバックされることを保証します。

非同期関数を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 

そして、そのようにそれを呼び出す:私はmy CoffeeScript bookでJSのイベントモデルについて少し詳しく説明し

Gmap('#canvas').getAddressBounds request.term, (data) -> console.log data 

だから、あなたが行うことができ、すべてのコールバックを使用するには、あまりにも、あなたの関数を変更で。また、John ResigのHow JavaScript Timers Workは必読です。非同期性には慣れていますが、マルチスレッド化のメリットは驚異的です。

2

変更 GMAP = ... にwindow.Gmap = ....

は、問題を解決します。理由は、coffeescriptが無名関数ですべてをラップすることです。あなたはより多くの機能の完全なモジュールシステムを使用する場合は何が起こっているここ

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

+0

これはスコープの問題を解決しますが、 '[] 'が返される問題は解決しません。 –

+0

あなたは正しいです、私は最も明白な問題しか見ませんでした。 Pity StackOverflowはOPが2つの答えを選択することはできません;) – bradgonesurfing

関連する問題