前段的功能愈來愈強大,如今實現同步的for循環輸出的方式也愈來愈多,咱們先看一個例子:html
forF(); function forF() { for (var i = 0; i < 3; i++) { setTimeout(function () { console.log(i); }, 1000) } } // 1s後輸出:3 3 3
相信你們對這個比較常見了,原理是由於var聲明的i爲forF的局部變量,setTimeout只是定時器,他暫時將內部函數掛起,等到一秒後執行,到那個時候,i已經變成了5。es6
那麼咱們的解決辦法有哪些呢?promise
先上一個es5之前的解決辦法:app
forF(); function forF() { for (var i = 0; i < 3; i++) { outF(i); } } function outF(i) { setTimeout(function () { console.log(i); }, 1000*i) } // 0 1 2
由於在循環中用了外部函數,那麼至關於建立了三個outF實例,由於i是基本變量,因此每一個實例的i都是不共享的,這裏要注意設置的定時器時間要1000*i;async
下面開始用es6的方法實現啦!
1.用塊做用域的let函數
forF(); function forF() { for (let i = 0; i < 3; i++) { setTimeout(function () { console.log(i); }, 1000*i) } }
由於let是塊做用域的,對於setTimeout函數而言,每次循環都新建立一個i,每一個i不共享es5
2.await(實際上是es7的)
見代碼code
var sleep = function (time) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve('ok'); }, time); }) }; // // 用await實現循環輸出數字 async function awaitF() { for (var i = 0; i < 3; i++) { await sleep(1000); console.log(i) } } awaitF() // 0 1 2
await顧名思義是等待,他接受一個promise對象,等待他相應而後才繼續執行。
注意用await的函數必須加async關鍵字
關於promise,推薦看大白話:https://www.cnblogs.com/lvdab...htm
3.yeild對象
function* countAppleSales () { for (var i = 0; i < 3; i++) { yield; console.log(i); } } var appleStore = countAppleSales(); // Generator { } appleStore.next(); nextApp(appleStore); function nextApp(appleStore) { setTimeout(function () { let done = appleStore.next().done; if (!done) { nextApp(appleStore); } }, 1000); }
yield函數必須定義成function* 外部在調用此函數的時候必須用next()方法他纔會繼續執行到下個yeild那裏,因此這裏用遞歸去執行。
關於yeild的知識點百度也不少,可自行百度。
後續會更新,歡迎補充