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

資訊專欄INFORMATION COLUMN

從閉包引出來(lái)的一系列問(wèn)題

TigerChain / 3068人閱讀

摘要:從閉包引出來(lái)的一系列問(wèn)題不起眼的開(kāi)始很明顯,由于異步的作用。追問(wèn)如果變成該怎樣處理首先可以使用閉包來(lái)解決這個(gè)問(wèn)題利用立即執(zhí)行函數(shù),來(lái)解決閉包造成的問(wèn)題。

從閉包引出來(lái)的一系列問(wèn)題 1. 不起眼的開(kāi)始
for(var i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(new Date, i)
    }, 1000)
}
console.log(new Date, i)

很明顯,由于異步的作用。到最后輸出的結(jié)果為6個(gè)5

如果用箭頭表示前后兩次輸出有1s的間隔,用,代表前后一起輸出,那么輸出結(jié)果是5->5,5,5,5,5

這個(gè)也很容易的就可以進(jìn)行解釋,先執(zhí)行console.log(),再進(jìn)行setTimeout()的異步操作。

追問(wèn)1:如果變成 5 -> 0,1,2,3,4 該怎樣處理?

首先可以使用閉包來(lái)解決這個(gè)問(wèn)題:

for(var i = 0; i < 5; i++) {
    (function(j) {
        setTimeout(function() {
            console.log(new Date, j)
        }, 1000)
    })(i)
}
console.log(new Date, i) // 5

利用立即執(zhí)行函數(shù),來(lái)解決閉包造成的問(wèn)題。

此外還可以使用setTimeout的第三個(gè)參數(shù) 文檔:

for(var i = 0; i < 5; i++) {
    setTimeout(function(j) {
        console.log(new Date, j)
    }, 1000, i)
}
console.log(new Date, i) // 5

可能會(huì)有很多同學(xué)采用ES6的方式來(lái)避免:

for(let i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(new Date, i)
    }, 1000)
}
console.log(new Date, i)

但是此時(shí)并不能正確輸出我們想要的結(jié)果,因?yàn)閘et聲明的 i 產(chǎn)生了塊級(jí)作用域,導(dǎo)致 for 循環(huán)外面的輸出不能獲取的 i ,所以此時(shí)會(huì)報(bào)錯(cuò) i is not defined

追問(wèn)2:如果把輸出變?yōu)?0->1->2->3->4->5 呢?

其中一種比較容易想到的方法:

for(var i = 0; i < 5; i++) {
    (function(j) {
        setTimeout(function() {
            console.log(new Date, j)
        }, 1000*j)
    })(i)
}

setTimeout(function() {
    console.log(new Date, i)
}, 1000*i)

但是js中定時(shí)器的觸發(fā)時(shí)機(jī)是不確定的,每次循環(huán)都會(huì)產(chǎn)生一個(gè)異步操作之后,會(huì)有一個(gè)輸出,那么完全可以使用Promise來(lái)解決這個(gè)問(wèn)題。

const tasks = []
for(var i = 0; i < 5; i++) {
    (function(j){
        tasks.push(new Promise((resolve) => {
            setTimeout(() => {
                console.log(new Date, j)
                resolve()
            }, j*1000)
        }))
    })(i)
}

Promise.all(tasks).then( () => {
    setTimeout( () => {
        console.log(new Date, i)
    }, 1000)
})

將上面代碼處理一下:

const tasks = []
const output = function(i) {
    new Promise( (resolve) => {
        setTimeout( () => {
            console.log(new Date, i)
            resolve()
        }, 1000*i)
    })
}

for(var i = 0;i < 5; i++) {
    tasks.push(output(i))
}

// 全部Promise執(zhí)行完畢,執(zhí)行最后一個(gè)輸出i
Promise.all(tasks).then( () => {
    setTimeout( () => {
        console.log(new Date, i)
    }, 1000)
})
追問(wèn)3:使用 async / await 怎么實(shí)現(xiàn)
// 模擬sleep
const sleep = (time) => new Promise((resolve) => {
    setTimeout(resolve, time);
});

(async () => {  // 聲明即執(zhí)行的 async 函數(shù)表達(dá)式
    for (var i = 0; i < 5; i++) {
        if (i > 0) {
            await sleep(1000);
        }
        console.log(new Date, i);
    }

    await sleep(1000);
    console.log(new Date, i);
})();

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

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

相關(guān)文章

  • 夯實(shí)基礎(chǔ)-作用域與閉包

    摘要:作用域分類作用域共有兩種主要的工作模型。換句話說(shuō),作用域鏈?zhǔn)腔谡{(diào)用棧的,而不是代碼中的作用域嵌套。詞法作用域詞法作用域中,又可分為全局作用域,函數(shù)作用域和塊級(jí)作用域。 一篇鞏固基礎(chǔ)的文章,也可能是一系列的文章,梳理知識(shí)的遺漏點(diǎn),同時(shí)也探究很多理所當(dāng)然的事情背后的原理。 為什么探究基礎(chǔ)?因?yàn)槟悴蝗ッ嬖嚹憔筒恢阑A(chǔ)有多重要,或者是說(shuō)當(dāng)你的工作經(jīng)歷沒(méi)有亮點(diǎn)的時(shí)候,基礎(chǔ)就是檢驗(yàn)?zāi)愫脡牡囊豁?xiàng)...

    daydream 評(píng)論0 收藏0
  • JS筆記

    摘要:從最開(kāi)始的到封裝后的都在試圖解決異步編程過(guò)程中的問(wèn)題。為了讓編程更美好,我們就需要引入來(lái)降低異步編程的復(fù)雜性。異步編程入門的全稱是前端經(jīng)典面試題從輸入到頁(yè)面加載發(fā)生了什么這是一篇開(kāi)發(fā)的科普類文章,涉及到優(yōu)化等多個(gè)方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結(jié)思考,循序漸進(jìn)的理解 TypeScript。 網(wǎng)絡(luò)基礎(chǔ)知識(shí)之 HTTP 協(xié)議 詳細(xì)介紹 HTT...

    rottengeek 評(píng)論0 收藏0
  • 【譯】閉包并不神秘

    摘要:下面我們就初步嘗試一下閉包現(xiàn)在來(lái)看一下發(fā)生了什么。于是,這種結(jié)構(gòu)就被稱作閉包。這就是閉包強(qiáng)大的地方。例如,如果我們可以在我們的計(jì)數(shù)器里面加一個(gè)名字我們可以往閉包里傳一個(gè)參數(shù)可以看出來(lái),在實(shí)現(xiàn)過(guò)程中不僅能記住局部變量,也記住了傳進(jìn)來(lái)的變量。 計(jì)數(shù)器 首先,從一個(gè)計(jì)數(shù)器開(kāi)始。 var counter = 0; function increment() { counter = cou...

    sevi_stuo 評(píng)論0 收藏0
  • javascript系列--javascript擎執(zhí)行的過(guò)程的理解--語(yǔ)法分析和預(yù)編譯階段

    摘要:所以覺(jué)得把這個(gè)執(zhí)行的詳細(xì)過(guò)程整理一下,幫助更好的理解。類似的語(yǔ)法報(bào)錯(cuò)的如下圖所示三預(yù)編譯階段代碼塊通過(guò)語(yǔ)法分析階段之后,語(yǔ)法都正確的下回進(jìn)入預(yù)編譯階段。另開(kāi)出新文章詳細(xì)分析,主要介紹執(zhí)行階段中的同步任務(wù)執(zhí)行和異步任務(wù)執(zhí)行機(jī)制事件循環(huán)。 一、概述 js是一種非常靈活的語(yǔ)言,理解js引擎的執(zhí)行過(guò)程對(duì)于我們學(xué)習(xí)js是非常有必要的??戳撕芏噙@方便文章,大多數(shù)是講的是事件循環(huán)(event loo...

    malakashi 評(píng)論0 收藏0
  • JS專題之去抖函數(shù)

    摘要:如果本次定時(shí)器沒(méi)有被清除,時(shí)間到后就會(huì)自然執(zhí)行事件處理函數(shù)。綁定去抖后的事件回調(diào)函數(shù)綁定回調(diào)函數(shù)的屬性方法,點(diǎn)擊頁(yè)面,重置去抖效果異步請(qǐng)求清空上一次事件觸發(fā)的定時(shí)器重置為從而下一次事件觸發(fā)就能立即執(zhí)行。 一、前言 為什么會(huì)有去抖和節(jié)流這類工具函數(shù)? 在用戶和前端頁(yè)面的交互過(guò)程中,很多操作的觸發(fā)頻率非常高,比如鼠標(biāo)移動(dòng) mousemove 事件, 滾動(dòng)條滑動(dòng) scroll 事件, 輸...

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

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

0條評(píng)論

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