2017-12-31 40 views
1

以下の実行順序は分かりません。大きなスクリプトのこの部分ですが、$("#select-overlay")がこれを開始します。JavaScriptの実行順序

function findSelectedMap(mapID) { 
    $.getJSON('maps.json', function (json) { 
     json.forEach(function (entry) { 
      if (entry.maps.id == mapID) { 
       changeLayerTo = entry.maps.url; 
       maxZoom = entry.maps.zoom; 
      } // end if 
     }); // end json.forEach 
    }); // end $.getJSON 
}  // end findSelectedMap 

function overlaySelector() { 
    $("#select-overlay").change(function() { 
     mapID = $("#select-overlay input[type='radio']:checked").val(); 
     findSelectedMap(mapID); // using mapID, find the url, zoom for overlayMap selected 
     currentLayer = L.tileLayer(changeLayerTo).addTo(map); 
     // more map stuff 
    }); // end $("#select-overlay"). 
} // end overlaySelector function 

overlaySelectorときのRailsアプリでページのロードが

<script> 
    $(document).on("turbolinks:load", function() 
    { 
    overlaySelector(); 
    }); 
</script> 

私はchangeLayerTocurrentLayer = L.tileLayer(changeLayerTo).addTo(map);前にライン5 に設定されるべきだと思うと呼ばれているが実行されます。 findSelectedMap(mapID)関数が入力されました(私はたくさんのconsole.logを追跡しています)。そして、実行はcurrentLayer = L.tileLayer(changeLayerTo).addTo(map);行にジャンプします(そしてエラーが発生しましたが、すぐ上にchangeLayerToを手動で定義して実行し続けることができ、json.forEach(function(entry)行が実行され反復

私は何が欠けていますか?当初はfindSelectedMap(mapID)overlaySelector機能に組み込まれていましたが、それが役立つかどうか確認するために引き出しましたすべての変数は関数の外で宣言されていますが、私は最良の方法で問題に近づいているとは思いませんが、URLとズームが必要です。 )。

+0

あなたはおそらく、 'change'イベントを含む' overlaySelector() 'を呼び出すでしょう。もちろん、 '#select-overlay'の' change'イベントが発生しインターセプトされると、 'changeLayerTo'が代入される前にコードが実行されます。 '$ .getJSON'も非同期であり、そのことを念頭におくのが最良です。 – Adriani6

+0

関数が呼び出されるまで関数は起動しません。 –

+1

ここでは非同期呼び出しが問題です。 '$ .getJSON'が実行されている間、すぐにcurrentLayerを割り当てます。 – Ele

答えて

2

次のことを試してみてください。

function findSelectedMap(mapID, cb) { 
    $.getJSON('maps.json', function (json) { 
     json.forEach(function (entry) { 
      if (entry.maps.id == mapID) { 
       changeLayerTo = entry.maps.url; 
       maxZoom = entry.maps.zoom; 
      } // end if 
     }); // end json.forEach 

     cb(); 
    }); // end $.getJSON 
}  // end findSelectedMap 

function overlaySelector() { 
    $("#select-overlay").change(function() { 
     mapID = $("#select-overlay input[type='radio']:checked").val(); 
     findSelectedMap(mapID, function() { 
      currentLayer = L.tileLayer(changeLayerTo).addTo(map); 
     }); // using mapID, find the url, zoom for overlayMap selected    
     // more map stuff 
    }); // end $("#select-overlay"). 
} // end overlaySelector function 

基本的には、CBのparamがちょうどforeachループの終了後に実行されるコールバック関数ですし、このラインcurrentLayer = L.tileLayer(changeLayerTo).addTo(map);は正しいchangeLayerToを使用します。

UPDATE - @ Adriani6としては示唆:彼らは

希望グローバルである必要はありません場合は、当然のことながら、ウィンドウオブジェクトにグローバルにそれらを割り当てるのではなく、コールバックを経由して戻って変数を渡す必要がありますこれは役に立ちます!

+1

これが当てはまる場合は、グローバルにする必要がない場合はもちろん、変数をウィンドウオブジェクトにグローバルに割り当てるのではなく、コールバック経由で戻す必要があります。しかしそれは小さな提案です。 – Adriani6

+0

@ Adriani6あなたが正しいですが、私はコードの流れについての詳細はありません。 – Ele

+0

正解です。それはマイナーな提案です。つまり、答えの一部としてOPを示唆していることを意味します(明らかにOPの提案として)。 – Adriani6