前端面試題中的 for迴圈 + setTimeout

來源:互聯網
上載者:User
js 定時器筆試題 分析以下代碼實際啟動並執行結果:
for (var i = 0; i < 5; i++) { setTimeout(function() {  console.log(new Date, i); }, 1000);}console.log(new Date, i);

JS 中同步和非同步代碼的區別、變數範圍、閉包等概念有正確的理解,就應該知道上面代碼的輸出結果:

Tue Mar 06 2018 10: 10: 26 GMT + 0800(中國標準時間) 5Tue Mar 06 2018 10: 10: 27 GMT + 0800(中國標準時間) 5Tue Mar 06 2018 10: 10: 27 GMT + 0800(中國標準時間) 5Tue Mar 06 2018 10: 10: 27 GMT + 0800(中國標準時間) 5Tue Mar 06 2018 10: 10: 27 GMT + 0800(中國標準時間) 5Tue Mar 06 2018 10: 10: 27 GMT + 0800(中國標準時間) 5
如果想間隔1s輸出一個數字,修改如下
for (var i = 0; i < 5; i++) {    setTimeout(function() {        console.log(new Date(), i)    }, i * 1000) // 這裡的將上面的1000改為i*1000}console.log(new Date(), i);

輸出的結果如下

Tue Mar 06 2018 12:20:28 GMT+0800 (中國標準時間) 5Tue Mar 06 2018 12:20:28 GMT+0800 (中國標準時間) 5Tue Mar 06 2018 12:20:29 GMT+0800 (中國標準時間) 5Tue Mar 06 2018 12:20:30 GMT+0800 (中國標準時間) 5Tue Mar 06 2018 12:20:31 GMT+0800 (中國標準時間) 5Tue Mar 06 2018 12:20:32 GMT+0800 (中國標準時間) 5
如果想輸出不同的數字,則需要使用閉包,這裡使用自執行函數,也可以使用 let 代替 var 聲明 i
for (var i = 0; i < 5; i++) {    (j => {        setTimeout(function() {            console.log(new Date, j)        }, j * 1000)    })(i) }console.log(new Date,i)

輸入結果如下

Tue Mar 06 2018 12:54:46 GMT+0800 (中國標準時間) 5Tue Mar 06 2018 12:54:46 GMT+0800 (中國標準時間) 0Tue Mar 06 2018 12:54:47 GMT+0800 (中國標準時間) 1Tue Mar 06 2018 12:54:48 GMT+0800 (中國標準時間) 2Tue Mar 06 2018 12:54:49 GMT+0800 (中國標準時間) 3Tue Mar 06 2018 12:54:50 GMT+0800 (中國標準時間) 4
使用Generator函數

Generator 函數是 ES6 提供的一種非同步編程解決方案.

for...of迴圈可以自動遍曆 Generator 函數時產生的Iterator對象,且此時不再需要調用next方法。

function* foo() {    for (let i = 0; i < 5; i++) {        yield i;    }    return 6;}for (let j of foo()) {    setTimeout(() => {        console.log(new Date, j)    }, j * 1000)}

輸出如下

Tue Mar 06 2018 13:41:39 GMT+0800 (中國標準時間) 0Tue Mar 06 2018 13:41:40 GMT+0800 (中國標準時間) 1Tue Mar 06 2018 13:41:41 GMT+0800 (中國標準時間) 2Tue Mar 06 2018 13:41:42 GMT+0800 (中國標準時間) 3Tue Mar 06 2018 13:41:43 GMT+0800 (中國標準時間) 4
使用ES7中的async函數

async 函數就是將 Generator 函數的星號(*)替換成async,將yield替換成await,僅此而已。

async函數返回一個 Promise 對象,可以使用then方法添加回呼函數。當函數執行的時候,一旦遇到await就會先返回,等到非同步作業完成,再接著執行函數體內後面的語句。

// 類比其他語言中的 sleep,實際上可以是任何非同步作業const sleep = (timeountMS) => new Promise((resolve) => {    setTimeout(resolve, timeountMS);});(async() => { // 聲明即執行的 async 函數運算式    for (var i = 0; i < 5; i++) {        await sleep(1000);        console.log(new Date, i);    }    await sleep(1000);    console.log(new Date, i);})();

輸出如下

Tue Mar 06 2018 13:52:22 GMT+0800 (中國標準時間) 0Tue Mar 06 2018 13:52:23 GMT+0800 (中國標準時間) 1Tue Mar 06 2018 13:52:24 GMT+0800 (中國標準時間) 2Tue Mar 06 2018 13:52:25 GMT+0800 (中國標準時間) 3Tue Mar 06 2018 13:52:26 GMT+0800 (中國標準時間) 4Tue Mar 06 2018 13:52:27 GMT+0800 (中國標準時間) 5
使用 Promise
function delay(time) {    return new Promise(function(resolve, reject) {        setTimeout(resolve, time);    })}for (let i = 0; i < 5; i++) {    delay(i * 1000).then(() => console.log(new Date, i))}

輸出如下

Fri Mar 16 2018 09:57:04 GMT+0800 (中國標準時間) 0Fri Mar 16 2018 09:57:05 GMT+0800 (中國標準時間) 1Fri Mar 16 2018 09:57:06 GMT+0800 (中國標準時間) 2Fri Mar 16 2018 09:57:07 GMT+0800 (中國標準時間) 3Fri Mar 16 2018 09:57:08 GMT+0800 (中國標準時間) 4

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.