Cách tốt hơn để có được thời gian tính bằng mili giây trong javascript?


141

Có một cách khác trong JavaScript là lấy thời gian tính bằng mili giây bằng cách sử dụng đối tượng ngày hoặc ít nhất là một cách để sử dụng lại đối tượng đó, mà không phải khởi tạo một đối tượng mới mỗi khi tôi cần lấy giá trị này? Tôi đang hỏi điều này bởi vì tôi đang cố gắng tạo một công cụ trò chơi đơn giản bằng JavaScript và khi tính toán "thời gian khung delta", tôi phải tạo một đối tượng Ngày mới mỗi khung. Mặc dù tôi không quá lo lắng về ý nghĩa hiệu suất của việc này, tôi đang gặp một số vấn đề với độ tin cậy của thời gian chính xác mà đối tượng này trả về.

Tôi nhận được một số "bước nhảy" kỳ lạ trong hoạt hình, cứ sau một giây và tôi không chắc điều này có liên quan đến Bộ sưu tập rác của JavaScript hay giới hạn của đối tượng Date khi cập nhật quá nhanh. Nếu tôi đặt giá trị delta thành một số hằng, thì hoạt ảnh nếu hoàn toàn mượt mà, vì vậy tôi khá chắc chắn rằng "bước nhảy" này có liên quan đến cách tôi có được thời gian.

Mã liên quan duy nhất tôi có thể cung cấp là cách tôi tính thời gian delta:

prevTime = curTime;
curTime = (new Date()).getTime();
deltaTime = curTime - prevTime;

Khi tính toán chuyển động / hoạt hình tôi nhân một giá trị không đổi với thời gian delta.

Nếu không có cách nào để tránh mất thời gian tính bằng mili giây bằng cách sử dụng đối tượng Date, thì một hàm sẽ tăng một biến (là thời gian trôi qua tính bằng mili giây kể từ khi trò chơi bắt đầu) và được gọi là sử dụng hàm SetTimer với tốc độ một lần mỗi mili giây là một sự thay thế hiệu quả và đáng tin cậy?

Chỉnh sửa: Bây giờ tôi đã kiểm tra mã của mình trong các trình duyệt khác nhau và dường như "bước nhảy" này thực sự chỉ rõ ràng trong Chrome, không phải trong Firefox. Nhưng nó vẫn tốt nếu có một phương pháp hoạt động trong cả hai trình duyệt.


5
Một đối tượng trên mỗi khung hình không
CodeInChaos

2
Về hoạt hình nhảy mỗi giây, điều này có liên quan gì đến thực tế là Date.getMillisecondschỉ trả về một phần nghìn giây trong giây hiện tại, tức là 0 đến 999? Bạn không sử dụng chức năng này trong ví dụ của mình, nhưng có lẽ nó đang được sử dụng ở nơi khác hoặc trên một nhánh khác?
Dan Ross

2
Là bước nhảy liên quan đến một số vấn đề độ phân giải mili giây kỳ lạ? Từ tài liệu Mozilla : "Khi sử dụng now () để tạo dấu thời gian hoặc ID duy nhất, hãy nhớ rằng độ phân giải có thể là 15 mili giây trên Windows". Điều đó có thể liên quan đến nấc cục?
zashu

1
@zashu đây là một thời gian dài trước đây, vì vậy tôi không nhớ bất kỳ chi tiết cụ thể nào cho ví dụ này. Nhưng đối với ứng dụng gần đây hơn, khi sử dụng Date.now () tôi không thấy nhảy nữa.
Colin Dumitru

Câu trả lời:


173

Hãy thử Date.now () .

Việc bỏ qua rất có thể là do thu gom rác. Thông thường, có thể tránh việc thu gom rác bằng cách sử dụng lại các biến càng nhiều càng tốt, nhưng tôi không thể nói cụ thể phương pháp nào bạn có thể sử dụng để giảm tạm dừng thu gom rác.


1
Tôi đã thử sử dụng Date.now (), nhưng tôi vẫn có các bước nhảy tương tự. Vì vậy, bây giờ tôi khá chắc chắn rằng đó không phải là vấn đề với bộ sưu tập rác, mà là hạn chế khi nhận các giá trị chính xác với đối tượng Date. Như tôi đã nói, việc thay thế thời gian delta bằng giá trị không đổi dẫn đến hoạt ảnh / chuyển tiếp mượt mà, do đó, bộ sưu tập rác duy nhất có thể xảy ra là với "Ngày mới" hoặc "Date.now ()" (nếu chức năng này khởi tạo các đối tượng của chính nó Tôi không biết về).
Colin Dumitru

22
Chỉ cần ngẩng cao đầu: Điều này không hoạt động trong IE8 trở xuống
Nick

1
Tôi làm: / Tất cả những gì tôi muốn là ngày tính bằng ms. Có vẻ rất phức tạp cho một cái gì đó rất cần thiết.
Damien Golding

5
@Prozi +1 .. IE thực sự rất tệ, khi tôi lập trình web Tôi thực sự không quan tâm đến IE, chỉ cần chrome và firefox ..........
TechLife 11/03/2015

3
@TechLife Bạn cũng nên cung cấp cho các trình duyệt Android, Safari và opera một dòng suy nghĩ, nhưng tôi đồng ý IE là một đống rác. Ý tôi là thật tệ khi MS đã từ bỏ và đang triển khai một trình duyệt mới trong W10
Dendromaniac

49

Tôi biết đây là một chủ đề khá cũ, nhưng để giữ cho mọi thứ cập nhật và phù hợp hơn, bạn có thể sử dụng performance.now()chức năng chính xác hơn để có được thời gian hạt tốt hơn trong javascript.

window.performance = window.performance || {};
performance.now = (function() {
    return performance.now       ||
        performance.mozNow    ||
        performance.msNow     ||
        performance.oNow      ||
        performance.webkitNow ||            
        Date.now  /*none found - fallback to browser default */
})();

2
Sự thay thế cuối cùng chỉ nên Date.nowthay vì một biểu thức hàm ẩn danh
Bergi

1
Cũng không hoạt động trong các trình duyệt cũ ngu ngốc, không may. May mắn thay, tôi đã thuyết phục khách hàng trả tiền cho tôi khi tôi lãng phí hỗ trợ IE7 và IE8.
Michael Scheper

2
| | function () {trả về Ngày mới (). getTime ()}
mmm

2
Đáng chú ý là performance.now()cho thời gian đơn điệu, không giống như thời gian từ Date. Điều đó có nghĩa là mọi cuộc gọi tiếp theo được đảm bảo trả về giá trị không nhỏ hơn cuộc gọi trước.
người dùng

48

Theo tôi biết bạn chỉ có thể có thời gian với Ngày .

Date.now là giải pháp nhưng không có sẵn ở mọi nơi: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/now .

var currentTime = +new Date();

Điều này cung cấp cho bạn thời gian hiện tại tính bằng mili giây.

Đối với bước nhảy của bạn . Nếu bạn tính toán nội suy chính xác theo thời gian khung delta và bạn không gặp một số lỗi làm tròn số , tôi đặt cược cho trình thu gom rác (GC).

Nếu có nhiều đối tượng tạm thời được tạo trong vòng lặp của bạn, bộ sưu tập rác phải khóa luồng để thực hiện sắp xếp lại bộ nhớ và sắp xếp lại bộ nhớ.

Với Chrome, bạn có thể thấy GC dành bao nhiêu thời gian trong bảng Timeline .

EDIT: Vì câu trả lời của tôi, Date.now()nên được coi là tùy chọn tốt nhất vì nó được hỗ trợ ở mọi nơi và trên IE> = 9.


4
Chức năng nào +phục vụ trong +new?
Andrew Scagnelli

33
Việc +đơn giản được truyền Datetới Number, đưa ra dấu thời gian unix tiêu chuẩn tính bằng mili giây. Bạn có thể nhận được giá trị này một cách rõ ràng bằng cách gọi(new Date()).getTime()
ngryman

9
@mikenelson: Không phải là khủng khiếp đối với tôi, điều này là hiển nhiên khi bạn biết cách ép buộc hoạt động. Điều đó nói, Date.now()được ưa thích bây giờ vì sự hỗ trợ của nó đủ lớn bây giờ.
ngryman

1
Tôi chỉ thích +hơn .getTime()... Nó đơn giản hơn và tôi không cần ghi nhớ tên hàm

2
@TravisJ Phím tắt tuyệt vời? Để lấy lại một giá trị số đã có trong máy tính của bạn, bạn tạo một đối tượng, hãy gọi một toán tử kiểm tra int và kích hoạt một chuyển đổi gọi hàm (valueOf) gọi phương thức chuyển đổi lớp gọi hàm (getTime) cuối cùng lấy giá trị Sau đó, đối tượng bị bỏ rơi cho số phận của nó và sau 1000 lần lặp của vòng lặp, bạn có 1000 đối tượng Ngày bị xóa yêu cầu bộ sưu tập rác treo ở đó đột nhiên bị đổ lại với nhau, và trong khi máy tính của bạn chậm trễ, bạn tự hỏi điều gì đang xảy ra. :) Tuyệt vời!
FrancescoMM

7

Nếu bạn có đối tượng ngày như

var date = new Date('2017/12/03');

sau đó, có phương thức inbuilt trong javascript để lấy ngày ở định dạng mili giây là valueOf ()

date.valueOf(); //1512239400000 in milliseconds format

2

Đây là một câu hỏi rất cũ - nhưng vẫn để tham khảo nếu những người khác đang xem nó - requestAnimationFrame()là cách phù hợp để xử lý hoạt hình trong các trình duyệt hiện đại:

CẬP NHẬT: Liên kết mozilla cho thấy cách thực hiện việc này - Tôi không cảm thấy muốn lặp lại văn bản đằng sau liên kết;)


4
Chào mừng bạn đến với Stack Overflow ! Bạn có thể muốn bao gồm một lời giải thích ngắn về những gì requestAnimationFramengăn chặn "bước nhảy" này như được mô tả trong câu hỏi. Cảm ơn!
Qantas 94 Nặng

2
Ngay cả với requestAnimationFrame, chúng tôi không có nghĩa là giả định tốc độ khung hình là như nhau trên tất cả các nền tảng, vì vậy chúng tôi vẫn cần kiểm tra thời gian hiện tại.
Tom Boutell
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.