異步和回調(diào)
function f1(callback){
setTimeout(function(){
console.log('別急肃廓,開(kāi)始執(zhí)行f1')
for(var i=0;i<10000;i++){
}
console.log('f1執(zhí)行完了')
callback()
},0)
}
function f2(){
console.log('執(zhí)行f2')
}
function f3(){
console.log('執(zhí)行f3')
}
f1()
f2()
f3()
//結(jié)果是:"執(zhí)行f2"
"執(zhí)行f3"
"別急智厌,開(kāi)始執(zhí)行f1"
"f1執(zhí)行完了"
//還是先同步執(zhí)行,再任務(wù)隊(duì)列執(zhí)行盲赊。
假設(shè)铣鹏,我這個(gè)f1必須要最先開(kāi)始執(zhí)行,比如向服務(wù)器發(fā)請(qǐng)求哀蘑,要數(shù)據(jù)诚卸。但是f1是異步的,立刻執(zhí)行f2绘迁,但是這時(shí)候還沒(méi)要到數(shù)據(jù)合溺,數(shù)據(jù)到了,f2已經(jīng)執(zhí)行完了缀台。
怎么辦呢棠赛?
回調(diào)。在f1里做個(gè)參數(shù)膛腐,比如叫callback,當(dāng)異步處理完成后睛约,把這個(gè)參數(shù)作為函數(shù)執(zhí)行,比如callback(),這時(shí)候哲身,運(yùn)行的指令也會(huì)變化:f1(f2),就是當(dāng)f1執(zhí)行完了辩涝,再去執(zhí)行f2。
很多異步函數(shù)里都有回調(diào)函數(shù)勘天,當(dāng)f1執(zhí)行后怔揩,得到數(shù)據(jù)或者什么結(jié)果,再去執(zhí)行f2脯丝。
function f1(callback){
setTimeout(function(){
console.log('別急商膊,開(kāi)始執(zhí)行f1')
for(var i=0;i<10000;i++){
}
console.log('f1執(zhí)行完了')
callback(i)
},0)
}
f1(function(value){
console.log(value)
})
//callback函數(shù)就是function(value){
console.log(value)
},也就是callback(i)
回調(diào)函數(shù)就是為了寫(xiě)的更好看巾钉,更方便翘狱。
函數(shù)節(jié)流
有些功能做的很頻繁秘案,比如說(shuō)偵聽(tīng)用戶滾動(dòng)砰苍,然后做一些事情潦匈,觸發(fā)滾動(dòng)幾十次,但是不希望函數(shù)執(zhí)行幾十次赚导,只是希望不滾動(dòng)了茬缩,再執(zhí)行。
搜索引擎吼旧,用戶在輸入東西時(shí)凰锡,下面自動(dòng)會(huì)有提示,可寫(xiě)一個(gè)字母就有提示圈暗,我希望在用戶輸入過(guò)程中不智能匹配掂为,直到我最后不輸入了,或者我兩秒內(nèi)沒(méi)有輸入字符员串,再匹配勇哗。前面連續(xù)輸入了,就不再智能匹配了寸齐。
var timer
function hiFrequency(){
if(timer){
clearTimeout(timer)
} //false欲诺,所以不執(zhí)行。直到300 毫秒后為真了渺鹦,執(zhí)行扰法,清除計(jì)時(shí)器。
//如果毅厚,300毫秒內(nèi)塞颁,又執(zhí)行了,這時(shí)候timer有值了吸耿,值從上一次在任務(wù)序列等待執(zhí)行中得到的賦值殴边,
//就清除定時(shí)器了,就清除了上次還沒(méi)執(zhí)行的了珍语,直到300毫秒里沒(méi)有執(zhí)行操作锤岸,才能刪除。
timer = setTimeout(function(){
console.log('do something')
},300) //剛開(kāi)始放任務(wù)隊(duì)列里板乙,timer沒(méi)值是偷,flase,所以不清除定時(shí)器募逞,300毫秒到了就輸出‘do something’,被清除了就不輸出了蛋铆。
}
hifRequency()
如圖一直執(zhí)行,就一直不輸出do something放接。
函數(shù)節(jié)流刺啦,先去判斷定時(shí)器是不是有了,沒(méi)有就在設(shè)置一個(gè)纠脾,有了就把上一次的清除掉玛瘸,重新設(shè)置蜕青,免得上一次的給這次的賦值了。
改造糊渊,封裝:
function throttle(fn,delay){
var timer= null
return function(){ //主函數(shù)右核,執(zhí)行結(jié)果就是返回這個(gè)函數(shù)
clearTimeout(timer) //清除定時(shí)器,這里清除的肯定是上一個(gè)定時(shí)器了,因?yàn)楸旧韼У倪€沒(méi)放到任務(wù)列表了渺绒。
timer= setTimeout(function(){
fn(arguments)
},delay) //定時(shí)器
}
}
function fn(){
console.log('hello')
} //這個(gè)是定時(shí)器執(zhí)行的方法
var fn2 = throttle(fn,1000) //想要的效果是一秒內(nèi)連續(xù)操作fn贺喝,就會(huì)不執(zhí)行定時(shí)器
fn2()
fn2()
fn2()