2014-08-27 6 views
1

JS에서 Date.now() 함수로 이상한 오류가 발생했습니다.JavaScript의 타임 스탬프가 일치하지 않습니까?

배경 정보 : 서버와 패킷을주고받는 웹 애플리케이션을 개발 중입니다. 들어오는 모든 패킷은 Date.now()에 의해 생성 된 타임 스탬프로 표시됩니다. 이러한 패킷 중에는 데이터가 있으며, 이는 챠트 차트에 인쇄됩니다. 그래서 나는 y 축의 값과 x 축의 타임 스탬프를 얻는다. 여태까지는 그런대로 잘됐다.

앱을 실행 시키면 이상한 행동이 나타납니다. -> 데이터 표를 과거의 데이터 포인트로 다시 그립니다. 내가 본 차트의 타임 스탬프를 확인하는 동안 내 차트는 모든 작업을 올바르게 수행하지만 타임 스탬프가 잘못되었습니다.

Chrome DevTools Console Error 1

방법 나중에 내가 서로를 얻을 : 몇 분 동안이 실행

var i = 0; 
var ts = [Date.now()]; 

setInterval(function() { 

    ts.push(Date.now()); 

    console.info("checking next timestamp ..."); 

    if (ts[i] > ts[i+1]) { 

     console.error("old timestamp (" + ts[i] + ") is BIGGER than current timestamp (" + ts[i+1] + ")!"); 
    } 

    i++; 

}, 100); 

나에게 하나의 오류를 인쇄 :

그래서 좀 더 많은 증거를 수집하기 위해, 약간의 테스트 스크립트를 작성 하나, 등등.

Chrome DevTools Console Error 2

이 테스트를 위해 나는 많은 타임 스탬프를 확인하는 100ms의 시간 간격을 선택했다. 하지만 내 응용 프로그램은 아마도 5s의 업데이트 간격을 가지고 있으며 여전히 가끔이 오류가 발생합니다. 아니 자주이 100ms와 같은,하지만

이 :(것

전에이 동작을 본 다른 사람이 내가 여기서 뭔가 잘못하고 있습니까 BTW

수 :? 내 응용 프로그램의 패킷은 하나 하나에 와서, 그래서이다 패킷의 순서가 뒤섞이는 것은 불가능합니다.

+0

Chrome, Firefox 및 IE에서도이 문제를 재현 할 수 없습니다. – Cerbrus

+0

@Cerbrus : Chrome을 사용하고 있으며 몇 분 후에이 오류가 발생합니다. 때로는 더 빨라지고, 때로는 더 오래 걸리는 경우가 있습니다 ... – Fidel90

+0

점심 시간에 실행을 떠나겠습니다 – Cerbrus

답변

0

어제 Performance API를 살펴 보았으므로 이제는이 방법이 적절하다고 생각합니다. 다음과 같이 응용 프로그램에 구현했습니다 :

매번 서버에서 입력 패킷을받을 때마다 타임 스탬프를 제공합니다. 지금까지 Date.now()가 이것을 깨달았지만 OS 또는 VM (또는 둘 모두)이 현재 시간을 수시로 재 계산할 때 일치하지 않을 수 있습니다.

이제는 내 자신의 타임 스탬프를 계산합니다. 이를 위해 응용 프로그램이 시작된 시간 소인을 읽어야합니다. 성능 API 나에게

는 윈도우 네임 스페이스에 존재하고 자신에 의해 전역 변수를 필요로하지 않기 때문에 그래서 내 응용 프로그램에서 모든 곳에서 사용할 수있는 값이이 값을 제공합니다. 아주 좋아.

이제 현재 타임 스탬프를 얻으려면 startTS 이후 내 응용 프로그램이 실행되는 시간을 나타내는 시간 값을 추가해야합니다. 이를 얻으려면 우리가 사용 필요한 경우 소수 부분이 필요하지 않을 수도로

var timeSinceStartup = window.performance.now(); //returns sth. like 1337.9836718 (ms with fractional part) 

, 하나는이 값을 반올림 할 수 있습니다

var rounded = (timeSinceStartup + 0.5) | 0; //same as but faster than Math.round(timeSinceStartup); 

글쎄, 나머지는 간단합니다.나는이를 테스트하기 위해 내 질문에서 작은 코드를 업데이트 한

var currentTS = startTS + timeSinceStartup; 

: 우리는 단지 그 값을 추가 (모두 밀리 초만큼) 짜잔해야

var i = 0; 
var start = window.performance.timing.navigationStart; 
var ts = [start + window.performance.now()]; 

setInterval(function() { 

    ts.push(start + window.performance.now()); 

    console.info("checking next timestamp ..."); 

    if (ts[i] > ts[i+1]) { 

     console.error("old timestamp (" + ts[i] + ") is BIGGER than current timestamp (" + ts[i+1] + ")!"); 
    } 

    i++; 

}, 100); 
크롬에서이 테스트를 실행

그 순간 (VM에서) 그리고 모든 것이 잘된 것 같습니다 (오류없이 17500 검사). 나는 sth가 궁금했을 텐데. 우리가 단조 증가 값으로 상수를 추가하기 때문에 다른 일이 일어날 것입니다.)

이 솔루션의 단점은 브라우저 지원 인 것 같습니다. 현재 모든 최신 브라우저가 있지만 Safari가이를 지원합니다. 내 앱이 최신 브라우저에서만 실행되도록 개발되었으므로 괜찮습니다.하지만 Safari의 부족은 나쁩니다.

http://caniuse.com/#feat=high-resolution-time

나는 crossbrowser 솔루션/polyfills/프레임 워크 또는 STH로 살펴해야합니다. 도움을 주신 모든 분들께 감사드립니다. 어쨌든 FF로 IE에서 Date.now()에 대한 해결책이 있을지 모르겠다면 궁금합니다. IE와 IE는 아무 문제가 없었습니다.

https://code.google.com/p/chromium/issues/detail?id=408077

편집이 누락 된 성능 API에 대한 좋은 polyfill 것 같다

: 그것은 Date.now()로 다시 떨어지면 당연히 https://gist.github.com/paulirish/5438650

, 브라우저에서 그래서 이전과 같은 문제가 발생할 수도있는 API를 지원하지 않습니다. 이 경우 앱에서 타임 스탬프를 계속 확인하고 타이밍 오류가 발생하면 자동으로 처리 할 것입니다 (예 : 차트에 그리지 않고 다음 값을 기다리는 등).

너무 길어 ...

관련 문제