經典閉包題目ES7新解

題目

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

輸出:5 (1s)5 5 5 5 5

如何變成: 5(1s)0(1s)1(1s)2(1s)3(1s)4

經典解法

閉包

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

ES6: let

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

追問

如何變成: 0(1s)1(1s)2(1s)3(1s)4 (1s)5

新解法

ES6: Promise

const tasks = []

const getPromise = i => 
  new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(new Date, i)
      resolve(i)
    }, i * 1000)
  })


for (let i = 0; i < 5; i++) {
  tasks.push(getPromise(i))
}

Promise.all(tasks).then(iArr => {
  setTimeout(() => {
    const i = [...iArr].pop() + 1
    console.log(new Date, i)
  }, 1000)
})

ES7: async/await

const sleep = time => new Promise(resolve => setTimeout(resolve, time)); // 這個分號不能省

(async () => {
	for (var i = 0; i < 5; i++) {
		console.log(new Date, i)
		await sleep(1000)
	}
	console.log(new Date, i)
})()

1 句尾分號不能省略的情況:

  • 下一行是 IFFE 的
  • 下一行是數組字面量的

2 套路:new 一個爲決議的 Promise, 其構造函數內使用定時器,定時器內 reslove

3 取一個數組最末尾的元素

  • arr[arr.length - 1]
  • [...arr].pop()
  • arr.slice(-1)[0]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章