0

私は次の場所に投稿されたプラグインコードを使用しています:

jQueryのヒントとコツ

...これは本質的に非同期タイマーループです:

jQuery.forEach = function (in_array, in_pause_ms, in_callback)
{
    if (!in_array.length) return; // make sure array was sent

    var i = 0; // starting index

    bgEach(); // call the function

    function bgEach()
    {
        if (in_callback.call(in_array[i], i, in_array[i]) !== false)
        {
            i++; // move to next item

            if (i < in_array.length) setTimeout(bgEach, in_pause_ms);
        }
    }

    return in_array; // returns array
};


jQuery.fn.forEach = function (in_callback, in_optional_pause_ms)
{
    if (!in_optional_pause_ms) in_optional_pause_ms = 10; // default

    return jQuery.forEach(this, in_optional_pause_ms, in_callback); // run it
};

この素晴らしいコミュニティの助けを借りて、私は「真に戻る」ことを学びました。または「falseを返します。」ループの次の反復に進むのと同じ効果があります。

また、プログラムで$ .forEachループ呼び出しを完全に強制終了(破棄)し、残りの反復を実行できないようにします。

このプラグインにメソッドを追加して、同時に実行されている他の呼び出しに影響を与えずに、プラグインへの特定の呼び出しを強制終了できるようにするにはどうすればよいですか?

私は次のような変数に呼び出しを割り当てることを考えました:

var foo = $.forEach(json, 1000, function(idx,item) { /* do stuff */ });

...後で他のインスタンスに影響を与えずに特定のインスタンスを参照するには、killメソッドを追加してfooで呼び出すにはどうすればよいですか?ajax呼び出しで使用されるfoo.abort()と同等のものが必要です。

できますか?もしそうなら、どのように?

4

2 に答える 2

0

これは実際には単なるサンプルコードであるため、いくつかの問題があります。

これは、expandoプロパティをin_arrayオブジェクトに追加するだけで軽減できます。

jQuery.forEach = function (in_array, in_pause_ms, in_callback)
{
    // Note, you should use $.isArray(), which is smarter than checking length.
    if (!$.isArray(in_array)) return false;
    in_array.valid = true;
    var i = 0; // starting index
    function bgEach()
    {
        if (!in_array.valid) return;
        if (in_callback.call(in_array[i], i, in_array[i]) !== false)
        {
            i++; // move to next item

            if (i < in_array.length) setTimeout(bgEach, in_pause_ms);
        }
    }

    // I moved this because you were calling it before it was defined.
    bgEach(); // call the function
    return in_array; // returns array
};

メソッドから生の配列オブジェクトを取得しているので、完了したらオブジェクトの「valid」プロパティをfalseに設定できます。

var foo = $.forEach(json, 1000, function(idx,item) { /* do stuff */ });
foo.valid = false;

validプロパティはsetTimeout再帰をキャンセルするため、これによりループが効果的に強制終了されます。

この種のコードはやや危険であることに注意してください。競合状態などに遭遇しますが、JSで疑似スレッドと非同期コードを実行し始めるとそれが起こります。

于 2012-04-13T01:39:42.527 に答える
-1

タイマーをコールバックに渡して変更することができます

if (i < in_array.length) setTimeout(bgEach, in_pause_ms);

if (i == in_array.length) clearTimeout(timeout);

これにより、アイテムの数だけループすることが保証されます。

jQueryforEachは次のとおりです。

jQuery.forEach = function (in_array, in_pause_ms, in_callback)
{
    if (!in_array.length) return; // make sure array was sent

    var i = 0; // starting index

    bgEach(); // call the function

    function bgEach(){
        var timeout;
        if (in_callback.call(in_array[i], i, in_array[i], timeout = setTimeout(bgEach, in_pause_ms)) !== false)
        {
            i++; // move to next item
            // if end of array, stop iterating
            if (i == in_array.length) clearTimeout(timeout);
        }
    }

    return in_array; // returns array
};

これを使用して、タイマーが特定の基準を満たしている場合にタイマーをクリアして、ループを終了することができます。例:

$.forEach([1,2,3], 1000, function(idx, item, timer) {
  if(item == 2) {
    clearTimeout(timer);
  }
});
于 2012-04-13T05:37:50.773 に答える