2016-12-14 3 views
1

Microsoft Edge에서 버그 인 것으로 나타났습니다. setInterval()에 대한 콜백은 print()가 실행되는 동안 때때로 호출됩니다. 결과적으로 허용되지 않아야하는 2 개의 JavaScript 함수가 병렬로 실행됩니다.Microsoft Edge : setInterval() 콜백이 print()와 동시에 호출되었습니다.

이 간단한 테스트 응용 프로그램에서는 동작을 볼 수 있습니다.

index.html을 :

<!DOCTYPE html> 
<html>  
    <head> 
    <script src="script.js"></script> 
    </head> 
    <body> 
    <input type="button" onclick="printPage()" value="Print"/> 
    </body> 
</html> 

script.js :

var isPrinting = false; 

setInterval(function tick() { 
    if (isPrinting) { 
    alert('Interval callback called conurrently with click handler!'); 
    } 
}, 10); 

function printPage() { 
    isPrinting = true; 
    try { 
    print(); 
    } 
    finally { 
    isPrinting = false; 
    } 
} 

https://plnkr.co/edit/eKMQEHjRiXzl1vzjzIEN

나는 "인쇄"버튼을 클릭하면, 내가 경고를 볼 것으로 예상하지 않는다, 그러나 나는 경계를 관찰한다.

환경 : 마이크로 소프트 에지 38.14393.0.0, 윈도우 10

이 버그인가, 아니면 내가 뭔가를 이해하지?

+2

경고를 사용하는 것이 디버깅에는 좋지 않습니다. 너 정말로 무엇을하려고하는거야? 그 간격의 목적은 무엇입니까? – epascarello

+1

A는 실제 응용 프로그램에서 문제가 발생하여 문제를 plunkr의 테스트 사례로 좁혔습니다. 원하는 경우 alert()을 console.log()로 바꿀 수 있습니다. 나는 방금 경고가 그것을 독자에게 더 쉽게 만들었다 고 생각했다. – Mike

답변

0

이다.

(function() { 
    var isPrinting = false; 
    var _setInterval = window.setInterval; 
    var _print = window.print; 
    var queue = []; 

    window.setInterval = function (fn, delay) { 
     var params; 
     if (arguments.length > 2) { 
      params = arguments.slice(2); 
     } 
     var wrapper = function() { 
      if (!isPrinting) { 
       fn.apply(null, params); 
      } 
      else { 
       //console.log('queuing...'); 
       // Queue only one callback per setInterval() call. This mimics Chrome and IE11's behavior. 
       if (!wrapper.queued) { 
        wrapper.queued = true; 
        queue.push(wrapper); 
       } 
      } 
     }; 
     _setInterval(wrapper, delay); 
    }; 

    window.print = function() { 
     //console.log('print begin'); 
     isPrinting = true; 
     try { 
      _print.apply(this, arguments); 
     } 
     finally { 
      //console.log('print end'); 
      isPrinting = false; 
      if (queue.length > 0) { 
       var _queue = queue; // Save the contents of the queue so that we have them when the timeout callback executes. 
       setTimeout(function() { 
        _queue.forEach(function (wrapper) { 
         wrapper.queued = false; 
         wrapper(); 
        }); 
       }); 
       queue = []; 
      } 
     } 
    } 
})();