简单谈谈setTimeout与setInterval
感謝踩過的坑
sf社區的第一篇文章。
最近在做一個拍賣的微信小程序,用到了定時器setTimout和setInterval,簡單談談這兩個api。
- setTimeout
最常見的用法就是第二種(第三種mdn文檔不推薦),如:
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返回的一個正整數編號,是定時器的唯一標識符。
- setInterval
在我看來基本上可以當成setTimeout的升級版,就像setTimeout循環調用自身,用法也跟setTimeout一樣,用完是也要記得用clearInterval清掉定時器。底層原理或許會有些不同,這里就不深究。
下面是我在微信小程序倒計時組件:
// 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 = `$ozvdkddzhkzd:${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
在最后,感謝踩過的坑,讓我成長!初來乍到,多多關照,希望能堅持寫技術博文。
總結
以上是生活随笔為你收集整理的简单谈谈setTimeout与setInterval的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面试题:各大公司Java后端开发面试题总
- 下一篇: 【译】数据结构中关于树的一切(java版