感謝踩過的坑sf社區(qū)的第一篇文章。最近在做一個(gè)拍賣的微信小程序,用到了定時(shí)器setTimout和setInterval,簡(jiǎn)單談?wù)勥@兩個(gè)api。
最常見的用法就是第二種(第三種mdn文檔不推薦),如:
var timeoutId = setTimeout(function() {
console.log('hello world!')
},1000)
定時(shí)器是先等待1000ms再執(zhí)行function的語句,而不是一開始就執(zhí)行然后再等待。如果執(zhí)行的語句需要用到this引用,需要在回調(diào)函數(shù)function上綁定this:function() {...}.bind(this),把this傳給回調(diào)函數(shù),同作為該回調(diào)函數(shù)的this,使回調(diào)函數(shù)內(nèi)外this的指向保持一致?;蛘哂胑s6的箭頭函數(shù)() => {},也能起到同樣的作用。bind的用法詳見Function.prototype.bind() 用完定時(shí)器之后,要記得清除:clearTimeout(timeoutId) 這里的timeoutId是setTimeout返回的一個(gè)正整數(shù)編號(hào),是定時(shí)器的唯一標(biāo)識(shí)符。
在我看來基本上可以當(dāng)成setTimeout的升級(jí)版,就像setTimeout循環(huán)調(diào)用自身,用法也跟setTimeout一樣,用完是也要記得用clearInterval清掉定時(shí)器。底層原理或許會(huì)有些不同,這里就不深究。 下面是我在微信小程序倒計(jì)時(shí)組件:
// components/countdown.js
/**
* 倒計(jì)時(shí)組件
*/
Component({
/**
* 組件的屬性列表
*/
properties: {
durationInit: {
type: Number,
value: 0,
observer: function(newVal) { //監(jiān)控duration初始值變動(dòng)(看有沒有外部傳入新的時(shí)間)
this.initDuration(newVal)
}
}
},
/**
* 組件的初始數(shù)據(jù)
*/
data: {
duration: 0, //剩余時(shí)間,單位秒
timeDisplay: '' //展示時(shí)間
},
intervalId: null, //計(jì)時(shí)器Id,不需要渲染,放外面,免得影響性能
/**
* 組件銷毀了要清除計(jì)時(shí)
*/
detached() {
this.stopInterval(this.intervalId)
},
/**
* 組件的方法列表
*/
methods: {
// 設(shè)置時(shí)間
setTime: function(duration) {
if (duration <= 0) {
this.setData({
timeDisplay: `活動(dòng)結(jié)束啦`
})
//this.data.timeDisplay = `活動(dòng)結(jié)束啦,戳這里看看好東西~`
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 = `$1ylmoexgailf:${h}:${m}:${s}`
//寫入
this.setData({
timeDisplay: time
})
return true
},
//倒計(jì)時(shí)
countDown: function(duration) {
//有沒有倒計(jì)時(shí)的必要.第一次展示時(shí)間(這個(gè)很重要)
var canCountDown = this.setTime(duration)
if (canCountDown === true) {
var intervalId = setInterval(
function() {
//清除計(jì)時(shí)器
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
}
},
//初始化剩余時(shí)間
initDuration: function(newVal) {
if (this.intervalId) {
//若有計(jì)時(shí)器,清除
this.stopInterval(this.intervalId)
}
this.setData({
duration: this.data.durationInit
})
this.countDown(newVal)
},
//清除計(jì)時(shí)器
stopInterval: function(intervalId) {
if (intervalId != null) {
clearInterval(intervalId)
this.intervalId = null
}
},
//格式化時(shí)間
formatTime(time) {
return time < 10 ? `0${time}` : `${time}`
}
}
})
最后想吐槽一下W3School,隨著學(xué)習(xí)的深入,發(fā)現(xiàn)W3School的坑真多,強(qiáng)烈建議不要看W3School學(xué)前端,要看MDN文檔。可能很多人的前端啟蒙就是W3School,我也是。名字跟W3C很像,還以為是非常專業(yè)的網(wǎng)站,然而后來發(fā)現(xiàn)跟W3C并沒有什么關(guān)系。W3School在baidu搜索排名非常高,被坑了,baidu也是同謀?,F(xiàn)在早已擁抱google,清爽!
通過上面3張圖片,可以看出
2. 不推薦的用法沒有指出,文檔更新慢,權(quán)威性極低 以上圖片均來源于MDN和W3School 在最后,感謝踩過的坑,讓我成長!初來乍到,多多關(guān)照,希望能堅(jiān)持寫技術(shù)博文。 |