2016-09-20 11 views
0

で直ちに呼び出されるので、コール時にコールバックを呼び出すスロットル関数を記述しようとしていますが、指定された間隔で一定の制限回数までしかコールしません。制限に達すると、コールバックは最初の間隔の後に呼び出されるキューにプッシュされます。setTimeout()はスロットル関数

const throttle = (cb, interval, maxCalls) => { 
    let calls = 0; 
    const records = []; 
    let totalCalls = 0; 
    return (...rest) => { 
     if(calls < maxCalls) { 
      calls++; 
      records.push(Date.now()); 
      totalCalls++; 
      cb.apply(null, rest); 
      setTimeout(() => { 
      calls--; 
      }, interval); 
     } else { 
      //cb within setTimeout being invoked immediately here 
      setTimeout(() => { 
       calls++; 
       records.push(Date.now()); 
       totalCalls++; 
       cb.apply(null, rest); 
       //console.log(allotedTime: interval - (Date.now() - records[(totalCalls-1)-maxCalls])); 
      }, interval - (Date.now() - records[(totalCalls-1)-maxCalls])); 
     } 
    } 
} 

const meow = (start, ...args) => { 
    console.log(Date.now() - start, ...args); 
} 

const burp = throttle(meow.bind(this, Date.now()), 10000, 2); 

setTimeout(() => burp('burp'), 0); // expect 2-7 'burp' 
setTimeout(() => burp('burp'), 5000); // expect 5000 'burp' 
setTimeout(() => burp('burp'), 6000); // expect 10000 'burp' 
setTimeout(() => burp('burp'), 7000); // expect 15000 'burp' 

主な問題は、何らかの理由で、他のをブロックすることで、機能はのsetTimeoutを待っていないとすぐに呼び出されています。構文がうまくいくように見えるので、なぜ呼び出されているのか分かりにくいです。これは、呼び出された後、出力されます:

setTimeout(() => burp('burp'), 0); //6 'burp' 
setTimeout(() => burp('burp'), 5000); //5001 'burp' 
setTimeout(() => burp('burp'), 6000) //6001 'burp' 
//allotedTime: 4005 
setTimeout(() => burp('burp'), 7000); //10008 'burp' 
//allotedTime: 4993 

あなたは上の行からの結果とallotedTimeを追加した場合、あなたは目的のログを取得しますことに気づくでしょう。見ていただきありがとうございます。

Link to repl

+0

私はなぜ関数が間隔で呼び出されるべきときに 'setTimeout'を使うのだろうと思います。関数 '' throttle''が何かを絞り込んでいない場合、関数の名前を変えるのは変です。 – zeroflagL

答えて

0

私は問題を完全に理解している場合確かに、しかし、あなたの期待に基づいていない、 他の間隔は次のようになります。コールバックが呼び出された後totalCallsがインクリメントされ

interval - (Date.now() - records[totalCalls-maxCalls])) 

ので。そのため、elseブロックの最初の文(setInterval()の前)にtotalCalls++;を追加するか、値を増やす(suggestion number 1)ことを期待しないでください。

+0

totalCalls ++をsetTimeoutの外に移動しました!どうもありがとう! – petertdinh

関連する問題