setTimeout和for循環(huán)引發(fā)的常識(shí)錯(cuò)誤

標(biāo)簽(空格分隔): javascript


最近想要去實(shí)現(xiàn)一個(gè)定時(shí)函數(shù),定時(shí)的去改變一個(gè)元素的opacity豌注,從而實(shí)現(xiàn)淡入淺出的效果伤塌,我寫出的代碼是這樣的

var pic=document.getElementById('picture')
for(var i=0;i<=10;i++){
    setTimeout(function(){
        pic.style.opacity=i*0.1
        console.log(i)
    },1000)
}

結(jié)果一直不變,在控制臺(tái)console.log(i)發(fā)現(xiàn)i一直沒變幌羞,每次輸出都是11寸谜,想了想是因?yàn)?code>setTimeout()函數(shù)是異步實(shí)現(xiàn)的,在開始回調(diào)函數(shù)的時(shí)候属桦,for循環(huán)早已經(jīng)結(jié)束了熊痴,而引用的i則是最后一次循環(huán)結(jié)束后i的值11。
那我就用閉包來保存i的值吧

for(var i=0;i<=10;i++){
(function(j){
    setTimeout(function(){
        pic.style.opacity=j*0.1
        console.log(j)
    },1000)
})(i)
}

試了一下聂宾,發(fā)現(xiàn)還是不行果善,這次console對(duì)了能正確輸出i的值,但這不是我想要的啊系谐,我要實(shí)現(xiàn)opacity定時(shí)改變巾陕,然而這個(gè)怎么是一秒就完成了?理想中的結(jié)果應(yīng)該是隔一秒輸出一個(gè)數(shù)啊纪他,我在查閱一些資料以后發(fā)現(xiàn)鄙煤,這已經(jīng)不是閉包能解決的了,由于javascript的單線程的機(jī)制茶袒,settimeout的執(zhí)行必然是在循環(huán)之后的梯刚,即使把倒計(jì)時(shí)時(shí)間設(shè)為0也是這樣。

我又嘗試了下不在循環(huán)里面寫 setTimeout薪寓,結(jié)果也是這樣

setTimeout(function () {
    console.log(1)
}, 3000);
setTimeout(function () {
    console.log(2)
}, 3000);
setTimeout(function () {
    console.log(3)
}, 3000);

結(jié)果是在3秒后連續(xù)輸出了123亡资,并沒有停頓3秒,因?yàn)?code>setTimeout這個(gè)倒計(jì)時(shí)函數(shù)的回調(diào)是異步執(zhí)行的向叉,這樣for循環(huán)的問題就可以解釋了锥腻,for循環(huán)執(zhí)行了多次setTimeout函數(shù),但是回調(diào)都是各自獨(dú)立的母谎,都是在1秒后執(zhí)行回調(diào)函數(shù)瘦黑,幾乎在同時(shí)把我想要的那個(gè)元素的opacity設(shè)置了11次,自然是看不到“淡入”的效果了奇唤」╄担看樣子我是把setTimeout函數(shù)當(dāng)成延時(shí)函數(shù)是不能這么寫的了,那還有沒有別的方法呢
方法肯定是有的冻记,可以去嘗試一下回調(diào)地獄

setTimeout(function(){
    console.log(1)
    setTimeout(function(){
        console.log(2)
        setTimeout(function(){
            console.log(3)
            ...
        },1000)
    },1000)
},1000)

這實(shí)際上就是遞歸調(diào)用自身睡毒,抽象一下

var makeInterval=function(){
    var times=0;
    var step=function(){
        console.log(times)
        times++
        if(times<10){
            setTimeout(step,1000)
        }
    }
    setTimeout(step,0)
}
makeInterval()

實(shí)際上還可以使用setInterval來寫這段代碼

var makeInterval=function(){
    var times=0;
    var timer=setInterval(function(){
        if(times==9){
            clearTimeout(timer)
        }
        console.log(times)
        times++
    },1000)
}
makeInterval()

關(guān)于使用setTimeout還是setIntervalstackoverflow上有解釋,基本上是可以互相替換的冗栗,本人更加推薦使用setInterval演顾,認(rèn)為它更適合實(shí)現(xiàn)間隔的功能供搀。
至此,已經(jīng)解決了 for 循環(huán)的 bug钠至,總結(jié)原因葛虐,還是自己對(duì)這個(gè)函數(shù)有點(diǎn)想當(dāng)然,然而真正去寫的時(shí)候才能發(fā)現(xiàn)問題棉钧,可能也有一些朋友會(huì)犯和我一樣的錯(cuò)誤屿脐,這里寫出來和大家分享一下。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宪卿,一起剝皮案震驚了整個(gè)濱河市的诵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌佑钾,老刑警劉巖西疤,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異休溶,居然都是意外死亡代赁,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門兽掰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芭碍,“玉大人,你說我怎么就攤上這事孽尽〗押荆” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵泻云,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我狐蜕,道長(zhǎng)宠纯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任层释,我火速辦了婚禮婆瓜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘贡羔。我一直安慰自己廉白,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布乖寒。 她就那樣靜靜地躺著猴蹂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪楣嘁。 梳的紋絲不亂的頭發(fā)上磅轻,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼克伊。 笑死皮官,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的撮躁。 我是一名探鬼主播漱病,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼把曼!你這毒婦竟也來了杨帽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤祝迂,失蹤者是張志新(化名)和其女友劉穎睦尽,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體型雳,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡当凡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纠俭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沿量。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖冤荆,靈堂內(nèi)的尸體忽然破棺而出朴则,到底是詐尸還是另有隱情,我是刑警寧澤钓简,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布乌妒,位于F島的核電站,受9級(jí)特大地震影響外邓,放射性物質(zhì)發(fā)生泄漏撤蚊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一损话、第九天 我趴在偏房一處隱蔽的房頂上張望侦啸。 院中可真熱鬧,春花似錦丧枪、人聲如沸光涂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)忘闻。三九已至,卻和暖如春恋博,著一層夾襖步出監(jiān)牢的瞬間服赎,已是汗流浹背葵蒂。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留重虑,地道東北人践付。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像缺厉,于是被迫代替她去往敵國(guó)和親永高。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 弄懂js異步 講異步之前提针,我們必須掌握一個(gè)基礎(chǔ)知識(shí)-event-loop命爬。 我們知道JavaScript的一大特點(diǎn)...
    DCbryant閱讀 2,707評(píng)論 0 5
  • 之前在網(wǎng)上看了很多關(guān)于setTimeout的文章,但我感覺都只是點(diǎn)到為止辐脖,并沒有較深入的去剖析饲宛,也可能是我腦袋瓜笨...
    jia58960閱讀 35,158評(píng)論 21 66
  • 9.26-9.30 第8章 馴服線程和定時(shí)器 定時(shí)器可以在js中使用,但它不是js的一項(xiàng)功能嗜价,如果我們?cè)诜菫g覽器環(huán)...
    如201608閱讀 583評(píng)論 0 2
  • 前言 根據(jù)上一篇文章艇抠,我們可知,node對(duì)回調(diào)事件的處理完全是基于事件循環(huán)的tick的久锥,因此具有幾大特征: 1家淤、在...
    游泳的石頭閱讀 6,179評(píng)論 3 23
  • 春風(fēng)卻蕭瑟,紅黃的落葉打在我的風(fēng)衣上瑟由,一片絮重、一片;我站在江邊樹下歹苦,極目望去青伤,江中的海子已經(jīng)愈游愈遠(yuǎn),直到消失在水天...
    朱大餅閱讀 300評(píng)論 1 1