2011-09-01 53 views
16

Cách tốt nhất để tăng thời gian đơn điệu trong JavaScript là gì? Tôi hy vọng một điều gì đó giống như số System.nanoTime() của Java.Tăng thời gian đơn điệu trong JavaScript?

Date() rõ ràng sẽ không hoạt động vì nó bị ảnh hưởng bởi thay đổi thời gian của hệ thống.

Nói cách khác, những gì tôi muốn là một < = b, luôn:

a = myIncreasingTime.getMilliseconds(); 
... 
// some time later, maybe seconds, maybe days 
b = myIncreasingTime.getMilliseconds(); 

Tốt nhất, ngay cả khi sử dụng các chức năng UTC trong Date(), nó sẽ trở lại những gì nó tin là thời điểm chính xác, nhưng nếu ai đó đặt thời gian ngược lại, lệnh gọi tiếp theo tới Date() có thể trả về một giá trị nhỏ hơn. System.nanoTime() không bị giới hạn này (ít nhất là cho đến khi hệ thống được khởi động lại).

Modification: [2012/02/26: không có ý định làm ảnh hưởng đến câu hỏi ban đầu, trong đó có một tiền thưởng]

Tôi không quan tâm biết “Hiện tường”, tôi muốn biết đã trôi qua thời gian với một số độ chính xác mà Date() không thể cung cấp.

+0

Ý anh là gì của phiên? Bạn chạy mã này ở đâu (trình duyệt, máy chủ)? – galambalazs

+0

[W3Schools] (http://www.w3schools.com/js/js_timing.asp) hiển thị nội dung tương tự. – undefined

+0

Xin lỗi, tôi đã nói rất ít. Hy vọng rằng sự thay đổi tôi vừa thêm là rõ ràng hơn. – danorton

Trả lời

10

Bạn có thể sử dụng window.performance.now() - kể từ khi Firefox 15, và window.performance.webkitNow() - Chrome 20]

var a = window.performance.now(); 
//... 
var delay = window.performance.now() - a; 
+0

Chức năng này cũng có sẵn trong IE10. – danorton

1

Firefox cung cấp đối số "chậm trễ" cho setTimeout ... đây là một trong những cách để thực hiện bộ đếm thời gian tăng đơn điệu.

var time = 0; 

setTimeout(function x(actualLateness) { 
    setTimeout(x, 0); 
    time += actualLateness; 
}, 0); 
+2

setTimeout không đảm bảo độ trễ tối đa. Tham số chỉ định mức tối thiểu, chỉ. Không có cách nào để xác định một cách dứt khoát lượng thời gian thực tế được truyền bằng setTimeout. – danorton

+0

xem https://developer.mozilla.org/en/DOM/window.setTimeout, >> Lưu ý: Trước khi Gecko 13 (Firefox 13.0/Thunderbird 13.0), Gecko đã chuyển một tham số bổ sung cho thường trình gọi lại, cho biết "thực tế độ trễ "của thời gian chờ tính bằng mili giây. Thông số không chuẩn này không còn được thông qua, tôi đã cập nhật câu trả lời của tôi – 4esn0k

4

Bản thân Javascript không có bất kỳ chức năng nào để truy cập vào nanoTime. Bạn có thể tải một java-applet để aqcuire thông tin đó, như benchmark.js đã làm. Có thể @mathias có thể làm sáng tỏ những gì họ đã làm ở đó…

7

Bạn có thể quấn Date() hoặc Date.now() để buộc nó phải đơn điệu (nhưng không chính xác). Sketch, chưa được kiểm tra:

var offset = 0; 
var seen = 0; 
function time() { 
    var t = Date.now(); 
    if (t < seen) { 
    offset += (seen - t); 
    } 
    seen = t; 
    return t + offset; 
} 

Nếu đồng hồ hệ thống được thiết lập trở lại tại một thời điểm nhất định, sau đó nó sẽ xuất hiện mà không có thời gian đã trôi qua (và một thời gian trôi qua có chứa khoảng thời gian đó sẽ không chính xác), nhưng bạn sẽ ít nhất không có đồng bằng âm. Nếu không có đặt lại thì giá trị này sẽ trả về cùng một giá trị như Date.now().

Đây có thể là giải pháp phù hợp nếu bạn đang viết vòng mô phỏng trò chơi, ví dụ: time() được gọi là cực kỳ thường xuyên - lỗi tối đa là số lần đặt trở lại thời gian giữa các cuộc gọi. Nếu ứng dụng của bạn không tự nhiên làm điều đó, bạn có thể gọi nó một cách rõ ràng trên setInterval, nói (giả sử rằng không được hosed bởi đồng hồ hệ thống), để giữ cho độ chính xác của bạn tại chi phí của một số thời gian CPU.


Nó cũng có thể là đồng hồ sẽ được thiết lập mong, mà không ngăn cản đơn điệu nhưng có thể có những ảnh hưởng không mong muốn như nhau (ví dụ một chi trò chơi quá lâu cố gắng để bắt kịp mô phỏng của nó cùng một lúc). Tuy nhiên, điều này không phải là đặc biệt có thể phân biệt với máy đã ngủ trong một thời gian.Nếu một sự bảo hộ đó là mong muốn, nó chỉ có nghĩa thay đổi tình trạng này bên cạnh một hiện có, với một ngưỡng liên tục cho sự tiến bộ có thể chấp nhận:

if (t > seen + leapForwardMaximum) { 
    offset += (seen - t) + leapForwardMaximum; 
} 

tôi sẽ đề nghị rằng leapForwardMaximum nên được đặt hơn 1.000 ms bởi vì, cho ví dụ: Chrome (nếu tôi nhớ chính xác) điều chỉnh bộ tính giờ trong các tab nền để kích hoạt không quá một lần mỗi giây.

+0

Có, điểm tốt và được trả lời như tôi đã hỏi ban đầu. Tôi đã sửa đổi câu hỏi ban đầu của mình để thêm yêu cầu độ chính xác. – danorton

+0

Một loại nhận xét rõ ràng không phải là vấn đề cho câu hỏi ban đầu theo cách được hỏi, nhưng nó có thể quan trọng đối với một số không-ít: Giải pháp này không xử lý trường hợp người dùng đặt đồng hồ về phía trước, tức là nó không ngăn chặn các bước nhảy tích cực lớn trong thời gian trả về. –

+0

@MarkusA. Nó có vẻ đáng để thảo luận, vì vậy tôi đã thêm một phần vào đó. –

Các vấn đề liên quan