關於倒計時的一些探討

關於倒計時的一些探討

最近項目中有應用到倒計時,其中出現了一些問題和問題的解決方案,以爲蠻有分享價值,因而決定寫篇文章記錄一下。後端

主要問題:如何保證倒計時以服務器時間爲準?

這是很廣泛的問題,雖而後端能夠作校驗,可是不免本地時間會和服務器時間存在誤差,致使用戶體驗並不友好。(明明本地時間已是倒計時結束了,但是仍是沒法正常展現該展現的功能)api

對於這個問題,咱們該選用setTimeout+循環的形式仍是setInterval。我的認爲仍是使用setInterval更加符合咱們的業務邏輯。服務器

方案1:每次倒計時去服務端請求時間

code:網絡

var myInterval = setInterval(function(){
//執行請求 獲取當前服務端時間 並進行相應操做
},1000)

這個方案對於稍微有點經驗的開發人員來講,都知道是不可取的。由於這會給服務器形成沒法想象的壓力,致使應用崩潰。好比我在這個頁面停留一分鐘,那麼請求就發送了60次,假如此時有100我的在訪問這個頁面,那麼一分鐘就有6000條請求,人數若是再增加,這絕對會形成沒必要要的服務器壓力。而且這個方案的倒計時,也會存在很大的偏差,由於請求存在延遲,跟你的網絡狀態也有很大的關係。code

方案2:從服務端返回以服務器時間爲基準的倒計時時間戳

code:接口

//假設請求獲取到一個時間戳 TIMEDIFF 

var myInterval = setInterval(function(){
    TIMEDIFF--;
    //執行頁面倒計時的渲染
},1000)

優勢:生命週期

  • 一個頁面只請求一次
  • 本地修改時間也沒法更改倒計時

缺點:開發

  • js自帶的計時器並非百分百準確依據所指定的時間,進行定時工做,影響其準確度的狀況有不少,假如頁面一直打開,那麼與實際的誤差量會愈來愈大。

改進版

//假設請求獲取到一個時間戳 TIMEDIFF 
var endTime = Date.now()+TIMEDIFF;//以本地時間爲基準得到一個結束時間
var myInterval = setInterval(function(){
    var countDown = endTime - Date.now()
    //每秒會獲取本地時間,這樣就算執行的週期不許確 
    //也能夠準確的獲取時間差

    //執行頁面倒計時的渲染
},1000)

方案3:入口js請求接口獲取本地時間與服務器時間的差值

//entry.js入口文件

...
if(!window.dateDiff){
    $.get('api/GetTimeDiff',
        {nowDate:Date.now()},
        function(dateDiff){
            window.dateDiff = dateDiff;
            //講時間差存在全局變量中,方便在其餘模塊中調用
    })
}
...

//other.js 其餘模塊
...
var myInterval = setInterval(function(){
    var countDown = endTime - Date.now()+dateDiff;
    //每秒會獲取本地時間,這樣就算執行的週期不許確 
    //也能夠準確的獲取時間差

    //執行頁面倒計時的渲染
},1000)
...

優勢:get

  • 入口文件獲取請求,使該請求只在頁面生命週期中請求一次
  • 準確度高,就算頁面打開好久仍是保持高準確度

缺點:io

  • 因爲每秒獲取當前時間,假若有人刻意在倒計時時期內,修改了時間將會致使倒計時異常。

總結

固然,解決方案確定不僅以上幾種,歡迎有想法的同窗補充。對比以上三個方案,第一個不可行,第二和第三本質上是相似的東西,只是第三種方案將差值從模塊中抽離出來,而且調用次數也下降了不少,我的會比較喜歡第三種方案。此文章會持續保持更新狀態,有想法,有問題的同窗均可以聯繫我!!

相關文章
相關標籤/搜索