0

長いポーリング(ajax)を実行していて、コードの次の部分をループしています。上下に実行されているコードがあります。このコードは、内部メッセージングシステムの一部です。メッセージが到着すると、ページの特定の部分が点滅します。ユーザーがメッセージを確認すると、JSON応答からdash_notifyが削除され、点滅をオフにする必要があります。下記参照:

if (data.dash_notify == '1') {
    var x = '#dash_notif_blink';

    function blinking(x) {
        timer = setInterval(blink, 10);

        function blink() {
            x.fadeOut(400, function () {
                x.fadeIn(400);
            });
        }
    }

    console.log("initiate_dash");
    blinking($(x));
} else if (!data.dash_notify) {
    console.log("good");

    clearInterval(timer);
}

このコードに送信される次のJSON応答は次のとおりです。

{"current_date_time":"January 8, 2013 - 4:02 pm","dash_notify":"1"}

上記のデータが渡された場合、最初の点滅を理解します。以下が合格した場合:

{"current_date_time":"January 8, 2013 - 4:02 pm"}

次に、エラーをスローします。

Uncaught ReferenceError: timer is not defined 

「else」部分が正しく機能するように修正する方法がわかりません。完全なdash_notify:1応答が送信されたときにコードが開始された場合、それは完全に機能します。ボタンが点滅し、ユーザーがメッセージを確認すると、dash_notify:1が送信されなくなり、ボタンの点滅が停止します。ただし、dash_notify:1が設定されていないときにコードが開始された場合、ClearIntervalをどう処理するかがわかりません。

基本的にelse部分を修正する必要があります。

別のtypeOf===undefinedスニペットを使用しようとしましたが、機能しません。

どんな助けでも大歓迎です。

ありがとうございました!

編集:

これは現在機能しています。タイマーはステートメントの上に定義されています

if(data.dash_notify == '1'){

                            var x = '#dash_notif_blink';

                        console.log("initiate_dash");
                        blinking($(x));

                        }else if (typeof timer != "undefined" && timer) { 
                            clearInterval(timer);
    }               
                    }

これは機能していますが、タイマーを強制終了しようとすることがありますが、実際には実行されません。これは頻繁に発生します。

4

5 に答える 5

3

timer内部関数の外部に存在しないため、機能していないようblinkingです。var timer;ここでは、関数の外部にどこかがないことを前提としていますblinking。これは、発生しているエラーを考えると非常に可能性が高いです。

これが起こっている理由:

私が正しく、timerコード内の他の場所で宣言していない場合は、関数var timerの先頭に暗黙的に追加されています。blinking

function blinking(x) {
    var timer;
    timer = setInterval(blink, 10);

    function blink() {
        x.fadeOut(400, function () {
            x.fadeIn(400);
        });
    }
}

これによりtimer、内にローカル変数が作成されblinkingます。クロージャーから渡すことは決してないので、その関数の外に出ると存在しません。したがってtimer、外部コンテキストに取り込むか(オプション1)、内部から利用できるようにするblinking(オプション2)必要があります。

何をすべきか:

そのクロージャの外部にアクセスしたい場合はtimer、次の2つのいずれかを実行する必要があります。

timer1:外で宣言するblinking

 var timer = null;
 if (data.dash_notify == '1') {
    var x = '#dash_notif_blink';

    function blinking(x) {
        //etc...

2:の戻り値にしますblinking

var t;

if (data.dash_notify == '1') {
    var x = '#dash_notif_blink';

    function blinking(x) {
        var timer = setInterval(blink, 10); //note the var keyword for best practice

        function blink() {
            x.fadeOut(400, function () {
                x.fadeIn(400);
            });
        }

        return timer;
    }

    console.log("initiate_dash");
    t = blinking($(x));

} else if (!data.dash_notify) {
    console.log("good");    
    clearInterval(t);
}

これらのいずれかが機能し、外部名前空間の汚染に関してはほぼ同じです。オプション2の方が好きです。なぜなら、ローカル変数を返す必要があるまでは、ローカル変数を操作する方が簡単だと思うからです。


編集:

あなたのコメントによると、ループは無限に実行されます。つまり、まったく新しい間隔を作成し、timer毎回変数を再割り当てしているということです。これは、私が上で説明した問題とは別の問題です。古い間隔はまだそこにあり、timerもはやそれを指していません。clearInterval(timer)では、これらすべての間隔をどのようにクリアできますか?それはできません、それは最新のものだけをクリアすることができます。

基本的に、あなたは物事を一度に点滅させようとしているたくさんのタイマーを持っています。

これにどのように対処するかは、何をしようとしているかによって異なります。最も簡単なことは、一度に実行している間隔を1つだけにすることです。つまり、timer毎回クリアする必要があります。

//same as option 1 above except for `clearInterval(timer)` at the 
//beginning of `blinking`
var timer = null;

if (data.dash_notify == '1') {
    var x = '#dash_notif_blink';

    function blinking(x) {
        clearInterval(timer); 
        timer = setInterval(blink, 10);

複数のタイマーを実行する必要がある場合は、それらすべてを配列などで追跡する必要があります。

var timers = [];
//...
   function blinking(x) {
        timers.push(setInterval(blink, 10));
//...
} else if (!data.dash_notify) {
   timers.forEach(function(timer) {
       clearInterval(timer);
   });
}
于 2013-01-08T22:06:13.750 に答える
0

timer関数でのみ宣言/初期化されているため、このエラーが発生しblinkingます。あなたが呼ぶ場所にはclearInterval(timer)timerは存在しません。

于 2013-01-08T21:33:39.583 に答える
0

コード全体を実際に表示しなかったため、タイプチェックで何が間違っていたかはわかりませんが、次のようになります。

if (typeof timer != "undefined" && timer) { 
    clearInterval(timer);
}
于 2013-01-08T21:25:41.843 に答える
0

基本的timerに、チェック手順に入る前に変数を定義します(ループ?):

var timer;

... some code ...

if ( data.dash_notify && data.dash_notify == '1') {
    ...
} else if (!data.dash_notify) {
    clearInterval(timer);
}

clearInterval( whatever ) 何の影響もなく電話をかけることができます。、、、文字列などであってwhateverも。存在することを確認してください。nullundefinedtimer

無効なIDをclearTimeoutに渡しても効果はありません(そして例外をスローしません)。(MDN)

于 2013-01-08T21:32:36.690 に答える
0

これは現在、美しく機能しています。 *助けてくれたすべての人に感謝します!*

if(data.dash_notify === '1' && t === null){

                    var x = '#dash_notif_blink';

                    function blinking(x) {
                        var timer = setInterval(blink, 10); //note the var keyword for best practice

                        function blink() {
                            x.fadeOut(400, function () {
                                x.fadeIn(400);
                            });
                        }
                        return timer;
                    }

                    console.log('initiate_dash_alert');

                    // Data is passed. Parse to see if dash alert should be called. Secondary protection for
                    // multiple timer creation.
                    if(t){return;}else{t = blinking($(x));}




                }else if (!data.dash_notify){    
                    clearInterval(t);
                    console.log('clear_dash_alert');
                    t = null;
                }else{
                    console.log(t);
                    console.log('no_push_events');

                }                   
于 2013-01-10T21:25:01.040 に答える