成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

你真會(huì)用setTimeout嗎?

jsyzchen / 3235人閱讀

摘要:什么交互都處理不了怎么辦簡(jiǎn)化復(fù)雜度復(fù)雜邏輯后端處理的多線程上面都是的做法,但是也是處理這種問(wèn)題的一把好手。換一種思路,上面就是利用實(shí)現(xiàn)一種偽多線程的概念。

教科書(shū)里面的setTimeout

定義很簡(jiǎn)單
setTimeout() 方法用于在指定的毫秒數(shù)后調(diào)用函數(shù)或計(jì)算表達(dá)式。

廣泛應(yīng)用場(chǎng)景
定時(shí)器,輪播圖,動(dòng)畫(huà)效果,自動(dòng)滾動(dòng)等等

上面一些應(yīng)該是setTimeout在大家心中的樣子,因?yàn)槲覀兤匠J褂靡膊皇呛芏唷?/p>

但是setTimeout真的有那么簡(jiǎn)單嗎?

測(cè)試題

一個(gè)題目,如果你在一段代碼中發(fā)現(xiàn)下面內(nèi)容

    var startTime = new Date();
    setTimeout(function () {
        console.log(new Date() - startTime);
    }, 100)

請(qǐng)問(wèn)最后打印的是多少?
我覺(jué)得正確答案是,取決于后面同步執(zhí)行的js需要占用多少時(shí)間。
MAX(同步執(zhí)行的時(shí)間, 100)。

再加一個(gè)題目,只有下面代碼

    setTimeout(function () {
        func1();
    }, 0)
    func2();

func1和func2誰(shuí)會(huì)先執(zhí)行?

這個(gè)答案應(yīng)該比較簡(jiǎn)單,func2先執(zhí)行,func1后面執(zhí)行。

再來(lái)一題

    setTimeout(function () {
        func1()
    }, 0)

    setTimeout(function () {
        func1()
    })

有什么差別?

0秒延遲,此回調(diào)將會(huì)放到一個(gè)能立即執(zhí)行的時(shí)段進(jìn)行觸發(fā)。javascript代碼大體上是自頂向下的,但中間穿插著有關(guān)DOM渲染,事件回應(yīng)等異步代碼,他們將組成一個(gè)隊(duì)列,零秒延遲將會(huì)實(shí)現(xiàn)插隊(duì)操作。
不寫(xiě)第二個(gè)參數(shù),瀏覽器自動(dòng)配置時(shí)間,在IE,F(xiàn)ireFox中,第一次配可能給個(gè)很大的數(shù)字,100ms上下,往后會(huì)縮小到最小時(shí)間間隔,Safari,chrome,opera則多為10ms上下。

上面答案來(lái)自《javascript框架設(shè)計(jì)》

好了,看了上面幾個(gè)題目是不是感覺(jué)setTimeout不是想象中那樣了。

setTimeout和單線程

下面是我自己的一些理解
首先需要注意javascript是單線程的,特點(diǎn)就是容易出現(xiàn)阻塞。如果一段程序處理時(shí)間很長(zhǎng),很容易導(dǎo)致整個(gè)頁(yè)面hold住。什么交互都處理不了怎么辦?

簡(jiǎn)化復(fù)雜度?復(fù)雜邏輯后端處理?html5的多線程?

上面都是ok的做法,但是setTimeout也是處理這種問(wèn)題的一把好手。

setTimeout一個(gè)很關(guān)鍵的用法就是分片,如果一段程序過(guò)大,我們可以拆分成若干細(xì)小的塊。
例如上面的情況,我們將那一段復(fù)雜的邏輯拆分處理,分片塞入隊(duì)列。這樣即使在復(fù)雜程序沒(méi)有處理完時(shí),我們操作頁(yè)面,也是能得到即使響應(yīng)的。其實(shí)就是將交互插入到了復(fù)雜程序中執(zhí)行。

換一種思路,上面就是利用setTimeout實(shí)現(xiàn)一種偽多線程的概念。

有個(gè)函數(shù)庫(kù)Concurrent.Thread.js 就是實(shí)現(xiàn)js的多線程的。

一個(gè)簡(jiǎn)單使用的例子,引入Concurrent.Thread.js

    Concurrent.Thread.create(function(){
        for (var i = 0;i<1000000;i++) {
            console.log(i);
        };
    });
    $("#test").click(function  () {
        alert(1);
    });

雖然有個(gè)巨大的循環(huán),但是這時(shí)不妨礙你去觸發(fā)alert();

是不是很厲害~

還有一種場(chǎng)景,當(dāng)我們需要渲染一個(gè)很復(fù)雜的DOM時(shí),例如table組件,復(fù)雜的構(gòu)圖等等,假如整個(gè)過(guò)程需要3s,我們是等待完全處理完成在呈現(xiàn),還是使用一個(gè)setTimeout分片,將內(nèi)容一片一片的斷續(xù)呈現(xiàn)。

其實(shí)setTimeout給了我們很多優(yōu)化交互的空間。

如何使用

setTimeout這么厲害,那么我們是需要在在項(xiàng)目中大量使用嗎?
我這邊的觀點(diǎn)是非常不建議,在我們業(yè)務(wù)中,基本上是禁止在業(yè)務(wù)邏輯中使用setTimeout的,因?yàn)槲宜吹降暮芏嗍褂梅绞蕉际且恍﹩?wèn)題不好解決,setTimeout作為一個(gè)hack的方式。
例如,當(dāng)一個(gè)實(shí)例還沒(méi)有初始化的前,我們就使用這個(gè)實(shí)例,錯(cuò)誤的解決辦法是使用實(shí)例時(shí)加個(gè)setTimeout,確保實(shí)例先初始化。
為什么錯(cuò)誤?這里其實(shí)就是使用hack的手段
第一是埋下了坑,打亂模塊的生命周期
第二是出現(xiàn)問(wèn)題時(shí),setTimeout其實(shí)是很難調(diào)試的。

我認(rèn)為正確的使用方式是,看看生命周期(可參考《關(guān)于軟件的生命周期 》),把實(shí)例化提到使用前執(zhí)行。

綜上,setTimeout其實(shí)想用好還是很困難的, 他更多的出現(xiàn)是在框架和類(lèi)庫(kù)中,例如一些實(shí)現(xiàn)Promis的框架,就用上了setTimeout去實(shí)現(xiàn)異步。
所以假如你想去閱讀一些源碼,想去造一些輪子,setTimeout還是必不可少的工具。

微信公眾號(hào)

博客地址

http://tangguangyao.github.io/

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/86185.html

相關(guān)文章

  • 線程池你真不來(lái)了解一下?

    摘要:所以說(shuō)我們的線程最好是交由線程池來(lái)管理,這樣可以減少對(duì)線程生命周期的管理,一定程度上提高性能。線程池不接收新任務(wù),不處理已添加的任務(wù),并且會(huì)中斷正在處理的任務(wù)。當(dāng)所有的任務(wù)已終止,記錄的任務(wù)數(shù)量為,線程池會(huì)變?yōu)闋顟B(tài)。線程池徹底終止的狀態(tài)。 前言 只有光頭才能變強(qiáng) 回顧前面: ThreadLocal就是這么簡(jiǎn)單 多線程三分鐘就可以入個(gè)門(mén)了! 多線程基礎(chǔ)必要知識(shí)點(diǎn)!看了學(xué)習(xí)多線程事半功倍...

    stdying 評(píng)論0 收藏0
  • 前端er,你真會(huì)用 async ?

    摘要:異步函數(shù)是值通過(guò)事件循環(huán)異步執(zhí)行的函數(shù),它會(huì)通過(guò)一個(gè)隱式的返回其結(jié)果。 async 異步函數(shù) 不完全使用攻略 前言 現(xiàn)在已經(jīng)到 8012 年的尾聲了,前端各方面的技術(shù)發(fā)展也層出不窮,VueConf TO 2018 大會(huì) 也發(fā)布了 Vue 3.0的計(jì)劃。而在我們(我)的日常中也經(jīng)常用 Vue 來(lái)編寫(xiě)一些項(xiàng)目。那么,就少不了 ES6 的登場(chǎng)了。那么話說(shuō)回來(lái),你真的會(huì)用 ES6 的 asyn...

    Jaden 評(píng)論0 收藏0
  • 笑出腹?。∮行┏绦騿T真會(huì)玩代碼注釋

    摘要:轉(zhuǎn)自網(wǎng)絡(luò),部分出自網(wǎng)友這是一個(gè)被代碼耽誤的詩(shī)人來(lái)一份年的代碼看看產(chǎn)品經(jīng)理要對(duì)此負(fù)責(zé)不敢看,也不敢問(wèn)官網(wǎng)上的注釋程序員正確發(fā)牢騷的地方閱讀源碼的人,心里一定的崩潰的第一天上班看到這段注釋就想辭職。 轉(zhuǎn)自網(wǎng)絡(luò),部分出自 Quora 網(wǎng)友 0、這是一個(gè)被代碼耽誤的詩(shī)人 1、來(lái)一份 19...

    tinyq 評(píng)論0 收藏0
  • 易探云:“夏日炎炎,有你真甜”活動(dòng),香港/韓國(guó)/美國(guó)/深圳云服務(wù)器優(yōu)惠活動(dòng)

    易探云怎么樣?易探云8月份上線夏日炎炎,有你真甜活動(dòng),降價(jià),降價(jià),給云服務(wù)器降價(jià)降溫了!購(gòu)買(mǎi)易探云服務(wù)器月付送QQ音樂(lè)豪華版綠鉆1月及云服務(wù)器年付送QQ音樂(lè)綠鉆豪華版1年,而且給云服務(wù)器四大驚喜,年付低至6折起!香港CN2(薦)可用區(qū)1核1G2M云服務(wù)器月付僅18元/月(首月優(yōu)惠),年付低至238元/年起;韓國(guó)cn2云服務(wù)器2核2G2M20G配置僅548元/年;美國(guó)bgp云服務(wù)器2核2G5M20G...

    番茄西紅柿 評(píng)論0 收藏2637
  • 你真會(huì)用 Babel ?

    摘要:安裝然后在的配置文件加入入口文件引入這樣就可以啦,還是可以減少很多代碼量的。是參數(shù),等同于執(zhí)行正常。這個(gè)包很簡(jiǎn)單,就是引用了和,然后生產(chǎn)環(huán)境把它們編譯到目錄下,做了映射,供使用。 引入 這個(gè)問(wèn)題是對(duì)自己的發(fā)問(wèn),但我相信會(huì)有很多跟我一樣的同學(xué)。對(duì)于 babel 的使用,近半年來(lái)一直停留在與 webpack 結(jié)合使用,以及在瀏覽器開(kāi)發(fā)環(huán)境下。導(dǎo)致很多 babel 的包,我都不清楚他們是干嘛...

    mochixuan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<