2016-09-20 2 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])) 

때문이다. 따라서 totalCalls++;을 else 블록의 첫 번째 문 (setInterval() 이전)으로 추가하거나 값이 증가 할 것으로 예상하지 마십시오 (제안 번호 1).

+0

totalCalls ++를 setTimeout 밖으로 이동하면 효과적입니다! 고마워요! – petertdinh

관련 문제