最近在作一個拍賣的微信小程序,用到了定時器setTimout和setInterval,簡單談談這兩個api。前端
最多見的用法就是第二種(第三種mdn文檔不推薦),如:es6
var timeoutId = setTimeout(function() { console.log('hello world!') },1000)
定時器是先等待1000ms再執行function的語句,而不是一開始就執行而後再等待。若是執行的語句須要用到this引用,須要在回調函數function上綁定this:function() {...}.bind(this)
,把this傳給回調函數,同做爲該回調函數的this,使回調函數內外this的指向保持一致。或者用es6的箭頭函數() => {}
,也能起到一樣的做用。bind的用法詳見Function.prototype.bind()小程序
用完定時器以後,要記得清除:clearTimeout(timeoutId)
這裏的timeoutId是setTimeout返回的一個正整數編號,是定時器的惟一標識符。微信小程序
在我看來基本上能夠當成setTimeout的升級版,就像setTimeout循環調用自身,用法也跟setTimeout同樣,用完是也要記得用clearInterval清掉定時器。底層原理或許會有些不一樣,這裏就不深究。api
下面是我在微信小程序倒計時組件:微信
// components/countdown.js /** * 倒計時組件 */ Component({ /** * 組件的屬性列表 */ properties: { durationInit: { type: Number, value: 0, observer: function(newVal) { //監控duration初始值變更(看有沒有外部傳入新的時間) this.initDuration(newVal) } } }, /** * 組件的初始數據 */ data: { duration: 0, //剩餘時間,單位秒 timeDisplay: '' //展現時間 }, intervalId: null, //計時器Id,不須要渲染,放外面,省得影響性能 /** * 組件銷燬了要清除計時 */ detached() { this.stopInterval(this.intervalId) }, /** * 組件的方法列表 */ methods: { // 設置時間 setTime: function(duration) { if (duration <= 0) { this.setData({ timeDisplay: `活動結束啦` }) //this.data.timeDisplay = `活動結束啦,戳這裏看看好東西~` return false } var s = this.formatTime(duration % 60) var m = this.formatTime(Math.floor(duration / 60) % 60) var h = this.formatTime(Math.floor(duration / 3600) % 24) var d = this.formatTime(Math.floor(duration / 3600 / 24)) var time = `${d}:${h}:${m}:${s}` //寫入 this.setData({ timeDisplay: time }) return true }, //倒計時 countDown: function(duration) { //有沒有倒計時的必要.第一次展現時間(這個很重要) var canCountDown = this.setTime(duration) if (canCountDown === true) { var intervalId = setInterval( function() { //清除計時器 if (this.data.duration <= 0) { this.stopInterval(intervalId) } this.setData({ duration: this.data.duration - 1 }) this.setTime(this.data.duration) }.bind(this), 1000 ) this.intervalId = intervalId } }, //初始化剩餘時間 initDuration: function(newVal) { if (this.intervalId) { //如有計時器,清除 this.stopInterval(this.intervalId) } this.setData({ duration: this.data.durationInit }) this.countDown(newVal) }, //清除計時器 stopInterval: function(intervalId) { if (intervalId != null) { clearInterval(intervalId) this.intervalId = null } }, //格式化時間 formatTime(time) { return time < 10 ? `0${time}` : `${time}` } } })
最後想吐槽一下W3School,隨着學習的深刻,發現W3School的坑真多,強烈建議不要看W3School學前端,要看MDN文檔。可能不少人的前端啓蒙就是W3School,我也是。名字跟W3C很像,還覺得是很是專業的網站,然然後來發現跟W3C並無什麼關係。W3School在baidu搜索排名很是高,被坑了,baidu也是同謀。如今早已擁抱google,清爽!
下面就拿setInterval的說明作例子,對比一下MDN和W3School,就知道後者有多坑了。函數
經過上面3張圖片,能夠看出
1. W3School含糊其辭,解釋不清楚,不詳細。用的時候容易出問題
W3School:週期性執行...請告訴我若是先執行了回調函數,再等待1秒,再執行回調函數,這算不算得上週期性??
MDN:詳細指出函數的每次調用會在該延遲以後發生性能
2. 不推薦的用法沒有指出,文檔更新慢,權威性極低
W3School:連舉的例子都是不推薦的用法,用code代碼串。。。
MDN:詳細指出使用code不推薦,不只如此,還發散性指出緣由和eval()同樣,真的很貼心很友好了學習
以上圖片均來源於MDN和W3School網站