Javascript實現秒殺倒計時(時間與伺服器時間同步)
現在有很多網站都在做秒殺商品,而這其中有一個很重要的環節就是倒計時。
關於倒計時,有下面幾點需要注意:
1.應該使用伺服器時間而不是本地時間(本地時間存在時區不同、使用者自行設定等問題)。
2.要考慮網路傳輸的耗時。
3.獲取時間時可直接從AJAX的響應頭中讀取(通過getResponseHeader('Date')來獲得),伺服器端不需要專門寫時間生成指令碼。
過程分析:
1.從伺服器讀到一個時間戳之後便開始計時,不考慮網路傳輸的耗時:
圖中的各項標註分別是(上面的時間線採用標準時間,與伺服器和頁面的時間均無關):
start——頁面項伺服器發起AJAX請求時的時間。
www_start——伺服器響應頁面的請求並返回時間戳給頁面的時間。
pc_start——頁面接受到伺服器返回的時間戳並開始計時的時間。
www_end——伺服器倒計時結束的時間。
pc_end——頁面倒計時結束的時間,同時也是使用者在倒計時結束那一刻點選按鈕的時間。
end——伺服器接收到使用者點選資訊的時間。
可以看出,即使在倒計時結束的那一刻(也就是秒殺開始那一刻)使用者就立即點選滑鼠,也會比實際開始搶拍的時間(www_end,即伺服器
倒計時結束的時間)晚一些(可以很容易的看出,這個時間差正好等於pc_start - start,也就是AJAX從開始傳送到接收到響應資訊的耗
時)。如果有些內行在頁面倒計時結束前用指令碼傳送請求,那麼其他使用者可就虧大了。所以,我們要解決掉這個時間誤差的問題。
2.為了解決時間誤差的問題,我們將把頁面倒計時的時間縮短一小截(由上面的分析可以得出,這一小截正好等於pc_start - start),使得
使用者在倒計時結束時傳送給伺服器的搶拍資訊正好在伺服器倒計時結束時被接收到:
圖中的各項標註與Pic.1中相同(時間線採用標準時間,與伺服器和頁面的時間均無關),新增的兩項標註的含義如下:
old_pc_end——在未對網路傳輸耗時進行處理的情況下pc_end的時間。
old_end——在未對網路傳輸耗時進行處理的情況下end的時間。
由Pic.2可見,網路傳輸耗時造成的時間誤差已經完全被彌補了,彌補的方法是“將倒計時結束的時間提前pc_start - start”。但是解決了網路傳
輸耗時造成的誤差問題,還有使用者電腦時間和伺服器時間不相同的問題,下面我們繼續討論。
3.使用者的電腦時間和伺服器時間一定是有差異的,甚至差幾個時區,怎麼解決這個問題呢?方法的要點如下:
A. 當頁面接收到伺服器返回的時間戳www_t時,立即開始計時。
B. 當頁面接收到伺服器返回的時間戳www_t時,立即計算本地時間和伺服器返回的時間戳的時間差t=new Date().getTime() - www_t*1000。
C. 仍然使用new Date().getTime()來計時,而不是使用setInterval()函式(計時器很不穩定,誤差也很大),但時間的顯示與程式的邏輯必須
基於本地時間和上一步(B中)求得的時間偏差t。
結論要點:
頁面從接收到伺服器響應的時間戳開始計時,計時的時長應減掉AJAX從傳送到接收整個過程的耗時,計時過程則使用本地時間來實現(本
地時間+時間偏差)。
有任何疑問或建議請留言,謝謝!