前端倒計時不許的問題


電商網站,團購類網站不少都有都有秒殺這個業務。秒殺天然涉及前端倒計時的問題。前端倒計時許考慮兩個問題:javascript

1.因爲js是單線程的,也就是阻塞的,定時可定會不許。不管setTimeout()仍是setInterval(),都有問題;html

二、打開瀏覽器,而後切換到其餘app,再次回到瀏覽器,這期間js可能中止執行的問題。前端

本質上來講,只須要兩個時間點就能夠了:當前時間、秒殺開始時間。有了這兩個數據,咱們就能夠倒計時了。兩個時間的差值就是咱們要倒計時的時間差,每隔1秒減小1/每隔1毫秒減小1。可是,當前的時間不要用new Date(),這是獲取手機的時間,若是用戶修改手機的時間,這個會跟隨變化的。基於此,當前的時間必須是服務端傳過來的。用戶每次打開網頁,都會傳服務器的當前時間。秒殺開始的時間通常是後臺配置好的,只要配置了,他就定了。是個不變的量。java

解決方法1ajax

  以服務器的當前時間爲倒計時的當前時間,上面提到須要考慮的那兩個問題都沒有解決,若是咱們實時同步服務器的當前時間,那麼這兩個問題就都解決了。
如什麼時候時同步呢?最早想到的是,時時調用一個後端的接口,這個接口返回服務器的當前時間。但實際上,咱們只須要跟服務器ajax交互就能夠了,請求一個服務器不存在的資源,咱們從返回中拿返回頭,再從這個頭中取服務器的當前時間。
這種方法就是不斷的同步服務器的事件。
詳細代碼參考:https://www.zhihu.com/question/28896402
https://zhuanlan.zhihu.com/p/20832837?refer=xiaojue後端

筆者的代碼:瀏覽器

   var this_start_time//指定秒殺開始的時間點,服務器傳過來的
    var this_count_down;//時間差:指定秒殺開始時間減去當前時間。能夠先不初始化。
  //校準倒計時的秒數函數
    function sync(){
          var xhr = new XMLHttpRequest();
          xhr.open('get', '/', true);
          xhr.onreadystatechange = function() {
          if (xhr.readyState === 3) {
              var now = xhr.getResponseHeader('Date');
              var nowTime = new Date(now).valueOf()/1000;//沒有毫秒值,咱們倒計時的最小單位是秒。有毫秒,不除以1000
              this_count_down =this_start_time - nowTime;
              xhr.abort();
            }
          };
          xhr.send(null);
          
      }
      //先對this_count_down初始化
      sync();
      if(this_count_down>0){
       setInterval(function(){
         sync();
              this_count_down--;
           },1000) 
      }else{ 
        alert('倒計時結束 ') 
      }

  

  以上代碼的欠缺是每次請求服務器,性能不佳。但好處也顯而易見,3個用戶同時訪問頁面,他們的倒計時結果基本上同樣的,秒殺變得比較公平。當服務器出現問題,請求不到服務器的當前時間,這個代碼會有問題,但這不是咱們考慮的問題。服務器

 

解決方法2app

  還有種解決的辦法,就是計算每次倒計時的偏差,你能知道第n次你倒計時的應該發生的時間,再跟當前的時間對比,這個偏差就在下次倒計時的時候考慮進去。這樣能夠保證偏差不累計。可是對於退出瀏覽器的行爲,這種實際上是有問題的。
這種方法是不斷校準倒計時的週期,而週期不可能爲負數,治標不治本。
詳細代碼參考:http://www.cnblogs.com/flash3d/archive/2014/05/08/3715600.html函數

 

2種方法,第1種更好,不會有任何問題。而第2種,筆者實驗的過程當中會有點問題。

相關文章
相關標籤/搜索