0

TLDR openlayersマップのパンの最後で実行される関数があります。連続して発射したくありません。


マップのパンの最後に実行される関数があります。鍋が終わってから3秒後まで機能を起動しないようにしたい。setTimeout が現在行っているように、関数をキューに入れて10回ほど起動したくありませんが。

関数の実行を n 秒遅らせて、何回呼び出されても 1 回だけ実行するにはどうすればよいですか?

    map.events.register("moveend", map, function() {
      setTimeout(SetLocation, 5000);
    });

移動:

moveend - triggered after a drag, pan, or zoom completes

上記のコードでも setTimeout(func, delay); を使用しています。実行時に複数回発生します。どうすればこれを防ぐことができますか?


4

4 に答える 4

3

要件を満たせば、単純な関数ラッパーを作成できます。

var executeOnce = (function (fn, delay) {
  var executed = false;
  return function (/* args */) {
    var args = arguments;
    if (!executed) {
      setTimeout(function () {
        fn.apply(null, args); // preserve arguments
      }, delay);
      executed = true;
    }
  };
});

使用例:

あなたのコードで:

map.events.register("moveend", map, executeOnce(SetLocation, 5000));

その他の使用法:

var wrappedFn = executeOnce(function (a, b) {
  alert(a + ' ' + b);
}, 3000);

wrappedFn('hello', 'world');
wrappedFn('foo', 'bar'); // this won't be executed...

ラップされた関数は、指定された時間だけ遅延され、1回だけ実行されます。

于 2010-05-24T03:39:55.620 に答える
2

UI の遅延については、「setTimeout」と組み合わせて「clearTimeout」を使用することをお勧めします。「setTimeout」を呼び出すと、通常は無視される ID が返されます。ただし、ID を保存すると、次に「setTimeout」を呼び出そうとしているときに、以前の「setTimeout」を (呼び出したことがないかのように) キャンセルできます。

あなたのケースで起こっていると私が想定しているのは次のとおりです。

(mouse move triggers callback)
setTimeout (1st)
(mouse move triggers callback)
setTimeout (2nd)
...
callback from 1st setTimeout is called
callback from 2nd setTimeout is called
...

ただし、clearTimeout を使用すると、次のようになります。

(mouse move triggers callback)
setTimeout (1st)
(mouse move triggers callback)
clearTimeout (1st)
setTimeout (2nd)
...
callback from last setTimeout is called

指定した JavaScript コードを更新するには:

var delayedSetLocationId = -1;
...
map.events.register("moveend", map, function() {
    if (delayedSetLocationId >= 0) {
        clearTimeout(delayedSetLocationId);
    }
    delayedSetLocationId = setTimeout(SetLocation, 5000);
}); 
...
function SetLocation(...) {
    delayedSetLocationId = -1; // setTimeout fired, we can't cancel it now :)
    ...
}
于 2010-05-24T04:07:05.567 に答える
1

これはまさに setTimeout の目的です。setTimeout が関数を 10 回呼び出している場合、投稿していないコードに何か問題があります。

また、setTimeout はスクリプトを停止しないことに注意してください。

于 2010-05-24T03:30:19.897 に答える
0

私は実際にこれについて小さな記事を書きました。これは、CMS が提案したものと似ています。

コード スニペットは次のようになります。

var delayonetimeaction = {

    oneTimeActions: {},

    /***
    ** Will wait the supplied "delay" until executing 
    ** the supplied "action" (function). 
    ** If called a second time before the with the 
    ** same id, the first call will be ignored and 
    ** instead the second will be used - that is the 
    ** second action will be executed after the second 
    ** supplied delay, not the first.
    ***/
    bind: function (delay, id, action) {

        // is there already a timer? clear if if there is
        if (this.oneTimeActions[id]) clearTimeout(this.oneTimeActions[id]);

        // set a new timer to execute delay milliseconds from last call
        this.oneTimeActions[id] = setTimeout(function () {
            action();
        }, delay);

    },

};

http://sds-digital.co.uk/post/2015/04/21/js-delayed-one-time-action.aspx

于 2015-04-21T16:40:55.657 に答える