【整理總結】前端必須要掌握的3種定時任務

2023-02-28 22:01:11

在前端中,定時是一個很重要的知識點,定時任務是無處不在的。下面本篇文章就來給大家整理總結前端必須要掌握的3種定時任務,希望對大家有所幫助!

一、無處不在的定時任務

定時任務,簡單的理解就是多久後做什麼,每隔多久做什麼 。你是否感覺到了,其實定時任務是一個無處不在的東西,

比如電商平臺的秒殺倒計時,每隔一秒就要執行一次,給你一種快要結束的緊迫感;比如我們從12306買車票,支付頁的倒計時,每隔一秒就會告訴你,你的訂單再不支付,票就不屬於;比如產品人員告訴我們,每天晚上12點,要備份A表的資料;比如頁面加完成後的1分鐘後,自動跳轉到其他某個頁面去。

再比如HR告訴你,下午3點去一下會議室,有重要的事情要談;比如每天9點你都不得不開始工作,遲到就不行;比如每天9:30都會開早會,組長總是風雨無阻,你不去他就看你不順眼;比如每個月15號才會發工資,早一天都不會給你;比如65歲才退休,他不管你35歲到65歲之間幹啥去了,也不管你是不是有公司嫌你35歲是大齡碼農了。

這都是定時器,他會在固定的時間告訴你,你必須去做這件事,程式中有程式碼去控制,生活中有一隻無形的手,你看不見,他卻控制著你。

二、setTimeout的使用

c52292a65f694894a4e3059d5b6456d5.png

1. setTimeout的使用場景

setTimeout的使用場景規定為多久後執行什麼,只執行一次。今天我們簡單實現一個場景,場景規定在頁面在載入完成之初不去載入某些東西,以減少首次載入的內容,降低首屏渲染的壓力。當首屏元件載入完成之後的500毫秒,我們才去載入一些額外的東西。

以vue為例,例如首屏都放在了a.vue下,我們知道mounted生命週期可以表示這個元件DOM已載入完成,但元件載入完成,不代表圖片和請求都已完成渲染了,所以我們預留了500毫秒,程式碼如下:

。。。 // 表示a.vue其餘程式碼
mounted() {
    let timeout1 = setTimeout(() => {
        // 需要延遲做的事情
        // 並且延遲完畢要清除setTimeout
        timeout1 = null;
        window.clearTimeout(timeout1);
    }, 500)
},
登入後複製

2. 替代setInterval

很多時候我們不建議使用setInterval,這個原因下面說,雖然setTimeout是單次執行,但執行完了再在裡面執行一次不就成了多次執行了嘛。

例如我們實現一個累加器,從0開始累加,超級棒的程式碼就像下面這樣,是不是很棒,我的程式碼又不是不能跑,就算程式碼不能跑,我能跑得了唄。

var num = 0;
setTimeout(() => {
    num += 1;
    setTimeout(() => {
        num += 1;
        setTimeout(() => {
            num += 1;
            ......
            setTimeout(() => {
                num += 1;
            }, 970)
        }, 970)
    }, 970)
}, 970)
登入後複製

但如果由於某些原因自己需要這份工作呢,自己跑不了,那就得把程式碼修改一下,讓他不這麼棒,變得辣雞一些

var num = 0;
function timeoutFn() {
   setTimeout(() => {
      num += 1;
      timeoutFn();
   }, 970)
   console.log('經海路大白狗看一下num吧', num);
}
timeoutFn();
登入後複製

三、setInterval的使用

88f33a1549994cbb941d3808db897856.png

1. setInterval的使用場景

很顯然,setInterval強調多次,定時的去執行。比如定時累加器,比如定時輪訓獲取而不用socket長連結,比如我們常見的輪播圖3秒動一次。今天我們不做數位累加1的場景,那樣太low了,我們做一個累加13的,而且當數值累加到大於等於100的時候再重新從0開始往上累加。

有沒有發現狗哥部落格的一個特點,我不斷的在強調專案場景,專案場景,就是希望你不要把知識點孤立起來,知識點是要用於實戰的,我們學再多開發知識點最終都是要走向公司去掙工資的。

var num = 0;
setInterval(() => {
   if (num >= 100) {
        num = 0;
   }
  num += 13;
}, 970)
登入後複製

2. 專案中會遇到的問題

由於瀏覽器和setInterval的特性。setInterval本身他建立的時候就在堆記憶體中進行了儲存,佇列在記憶體中一直存在,也保證了到下一個時間可以準時的執行,而結合瀏覽器的特性,瀏覽器發現這個堆記憶體後,進行了一定的優化處理。當你的瀏覽器頁籤不處於螢幕最上方的時候,瀏覽器則會將這個定時任務進行掛起操作,等這個瀏覽器頁籤再恢復到最上層的時候,瀏覽器再恢復其執行。

所以我們會經常發現一個問題,例如輪播圖正在準時3秒動一次,然後瀏覽器被切走了,等你隔一段時間回來後呢,輪播圖就像瘋了一樣的轉動,然後再繼續恢復為3秒一動;又或者是在IOS還是什麼環境下來著,我記得當時是做一個倒計時的功能。當瀏覽器切走之前還剩12分鐘,等瀏覽器切走之後呢,倒計時就不動了,等過了2分鐘再切回來的時候,發現還是12分鐘,又開始倒計時。

其實這個時候可以檢測當前瀏覽器是否處於使用者眼前(或者說是否被切走了),用這個程式碼來判斷:

var countSecondFn = null;
function goOnCount() {
    countSecondFn = setInterval(() => {
        // 任務執行
    })
}
document.addEventListener('visibilitychange',function(){
   if(document.visibilityState=='hidden'){
      window.clearInterval(countSecondFn);
      countSecondFn = null;
    }else if(document.visibilityState=='visible'){
      goOnCount(); 
    }
});
登入後複製

所以很多時候,我們更希望用setTimeout的遞回來替換掉setInterval的執行,減少更多的問題。

四、node-schedule的使用

1. node-schedule的使用場景

node-schedule目前主要用於node伺服器端,例如我們的一些頁面,資料是設定出來的,那麼就沒有必要每次都去請求資料庫,再返回給前端,可以定時一下,幾分鐘傳送一次請求即可;再比如我們每次升級上線,為了保證一個良好的效能,HTML可能會部署在伺服器端,而靜態資源則部署在另外的伺服器。這樣靜態資源從v1.0升級到v1.1,則可以定時的去獲取設定平臺的版本號,然後動態拼接到HTML頁面上,以保證可以每次升級拿到最新的靜態資源。

但node-schedule和setInterval有本質上的區別。node-schedule更強調哪一天哪個小時,哪一分鐘,哪一秒鐘準確的去執行。就像我們經常被告知你明天早上9點去做一件什麼事情,每天晚上9點你才可以下班。這樣的場景,恐怕setInterval不能夠勝任了。

2. 簡單使用node-schedule

例如每到10分(3點10分、8點10分。。。12點10分)的時候,我們去請求一下資料,第一次請求到的資料進行快取處理,再次請求到的資料與老資料進行對比,如果無更新則繼續用快取資料,如果有更新則利用新資料。

const schedule = require('node-schedule');
let job = schedule.scheduleJob('* 10 * * * *', () => {
 axios(url, data, (res) => {
    // 與快取資料對比
    // 後者再犯個懶,不對比,每次都用新資料,請求異常了再用快取資料
 })
});
登入後複製

3. 執行鑰匙Corn

上一段程式碼中的 * 10 * * * * 呢,就是所謂node-schedule的定時鑰匙,這6個星號從左到右表示:秒 分 小時 天 月 年 ,這樣看是不是就更明白他的準確性和與setInterval的區別了。

4. Corn在專案中的問題

竟然這個Corn定時鑰匙如此準確,規定了哪一分鐘那一秒鐘去執行,去取資料,比如你寫的是每分鐘的第10秒去獲取,這本沒有問題。比如全公司都公用一個設定平臺呢,你每分鐘的第10秒去獲取,那比如你這個專案用到了N臺機器呢,這N臺是否要都是每分鐘的第10秒去獲取?那如果全公司的N個業務系統都這麼寫呢,會有什麼問題呢?哈哈,如果聽明白了狗哥的意思,歡迎和狗哥交流。

5. 自學前端有沒有必要學習node

其實我覺得對於自學前端,急於找到前端開發工作的人,沒有太大必要去學習node伺服器端知識。你基本把純前端的知識學到位已經很不容易了。但如果有時間,還是建議簡單學習一下,哪怕只是搭個koa的架子,練習著寫一下介面資料格式。一旦自己練習寫過介面資料,自己再從前端傳送ajax呼叫一下,我相信你將會有一個更全面的對開發專案的認知,在你遇到問題的時候,有更多的解決思路。

但如果你沒有學透,千萬別在簡歷上寫你精通node伺服器端,也別給自己挖坑說自己做過。你不說他們也不會問,這不丟人,放心吧。

五、定時器程式碼之外的思考

1ff019b05fa144ef9cedd9c9a3cd75b9.png

狗哥覺得其實即便你做了開發,也不應該生活中只有開發,我們努力工作是為了生活,為了更好的生活,所以狗哥更偏向於基於故事講基礎知識點,也更喜歡著力於知識點冒出個小故事(這句話換成抓手咋說?)。

慢慢的,習慣了開發中的定時任務,我們清楚的知道幾秒後該讓網頁執行一件什麼事,每天幾點該執行一件什麼事,可能覺得已經能夠勝任工作了,但久而久之,你到了一定的時刻就必須得離開學校,賴在那裡也沒有用,到了一定的時機,你就需要結婚生子去面對。沒人有強拉著你9點前必須到公司,但你知道9點前不到不行。老闆告訴你這個東西下班就得做出來,你不做出來也行啊,但你知道你必須做出來。

人生就像一個大的定時器,大的定時器裡面又環環緊扣了一個個的小定時器,他們無形卻似有形,直到那個你不知道的永恆。

【推薦學習:】

以上就是【整理總結】前端必須要掌握的3種定時任務的詳細內容,更多請關注TW511.COM其它相關文章!