2009-06-05 10 views
4

私はGoogleマップにプロットされる大量のデータを持っています。データセットのサイズのため、Googleマップは常にすべてのポイントがプロットされるまで数秒間フリーズします。ローディング中にアニメーションスピンサークルを使用して進行中であることを示しました。しかし、エンドユーザは行動を見ることを好む。彼らは一度にすべてではなく、段階的に地図上にプロットされたデータを求めています。 javascriptはマルチスレッドをサポートしていないので、これに最も近い方法は何ですか?UIの応答性とjavascript

+0

私はGoogleマップを使いこなしていません。これはどれくらいあなたのコントロールにあり、どれくらいがGoogleにあるのですか? – Nosredna

答えて

7

Javascriptエンジンは、キューの種類から1つずつ機能を実行します。関数は、スクリプトによって、またはユーザーのアクション(イベントハンドラー)の結果としてそこに置くことができます。したがって、長時間実行されるタスクを小さな短期実行サブタスクに分割し、ユーザーのアクションに応答する関数と混合できるように、この「キュー」にフィードすることが考えられます。
これは、ウィンドウのsetTimeoutをゼロ遅延で呼び出し、サブタスクを関数として渡すことで実行できます。 UIイベントハンドラを実行するためにこのように、あなたはチャンスを与えるだろう、以前ここで

function plotSpot(spot) { 
    // adding spots to map 
}; 
var spots = [1,2,3,4,5,6,7,8,9,10,11,12]; 
var plotSpotsBatch; 
plotSpotsBatch = function() { 
    var spotsInBatch = 10; 
    while(spots.length > 0 && spotsInBatch--) { 
     var spot = spots.shift(); 
     plotSpot(spot); 
    } 
    if (spots.length > 0) { 
     setTimeout(plotSpotsBatch, 0); 
    } 
}; 
plotSpotsBatch(); 

アレイのプロトタイプのための拡張機能です:

Array.prototype.forEachInBatches = function(batchSize, func) { 
    var arr = this; 
    var i = 0; 
    var doer; 
    doer = function() { 
     setTimeout(function() { 
      for (var stopBatch = i + batchSize; i < stopBatch && i < arr.length; i++) { 
       func(arr[i], i); 
      } 
      if (i < arr.length) { 
       doer(); 
      } 
     }, 0); 
    }; 
    doer(); 
}; 

使用例は、(あなたがID「スポット」どこかでdiv要素を持っている必要があります資料)。スポットの数に等しい違い、設定バッチサイズを確認するには:musicfreakが言ったことに

var spots = []; 
for (var i = 0; i < 10000; i++) { 
    spots.push('{x: ' + Math.ceil(Math.random() * 180) + ', y: ' + Math.ceil(Math.random() * 180) + '}'); 
} 
spots.forEachInBatches(10, function(spot, i) { 
    document.getElementById('spots').innerHTML += spot + (i < spots.length ? '; ' : ''); 
}); 
+0

私はこの解決策が好きです。シンプルで直感的です。 – airportyh

4

それぞれを短い遅延(setTimeout)でバッチでプロットできますか?

4

JavaScriptは通常複数のスレッドをサポートしていない可能性がありますが、その効果を得ることができます。

function spawnThread(func, params){ 
    window.setTimeout(
     (function(f, p){ 
     return function(){ 
      f.call(p); 
     } 
    )(func, params), 0 
    ) 
} 

この方法の主な問題点は、当然のことながら、糸の成功にチェックされるだろう、私は偉大な解決策ではないでしょう、あなたはグローバル変数または類似のものを使用して、これを管理できると仮定したが、それは動作します。

+2

タイムアウトを設定しても、新しいスレッドは作成されません(JavaScriptは常に1つのスレッド内で起動します)。このテクニックを使用する代わりに、長いタスクを小さなものに分けて実行を延期してから、前のタスクが実行され、ブラウザが簡単に実行されるまで実行を延期します。 –

+0

setTimeoutは実際にはスレッドを生成しません。 setTimeoutは、少なくとも指定されたミリ秒数が経過するまで実行を延期します。 –

1

同様に、しかし、Gearsを必要としない、Javascript web workersです。これは、今のところ最新バージョンのブラウザでのみ実装されています。