javascript|经典闭包题目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
【javascript|经典闭包题目ES7新解】3 取一个数组最末尾的元素
  • arr[arr.length - 1]
  • [...arr].pop()
  • arr.slice(-1)[0]

    推荐阅读