经典闭包处理
1:闭包
for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log(new Date(), i)
}, 1000)
}
console.log(new Date(), i) // 5 -> 5,5,5,5,5
1
2
3
4
5
6
7
2
3
4
5
6
7
改进一:IIFE
for (var i = 0; i < 5; i++) {
;(function (j) {
// j = i
setTimeout(function () {
console.log(new Date(), j)
}, 1000)
})(i)
}
console.log(new Date(), i)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
改进二:setTimeout 传值
for (var i = 0; i < 5; i++) {
setTimeout(
function (j) {
console.log(new Date(), j)
},
1000,
i
)
}
console.log(new Date(), i)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
改进三:函数传值
var output = function (i) {
setTimeout(function () {
console.log(new Date(), i)
}, 1000)
}
for (var i = 0; i < 5; i++) {
output(i) // 这里传过去的 i 值被复制了
}
console.log(new Date(), i)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
改进四:使用 let
for (let i = 0; i < 5; i++) {
setTimeout(
function (j) {
console.log(new Date(), j)
},
1000,
i
)
}
console.log(new Date(), i)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
1:ES6
- 0 -> 1 -> 2 -> 3 -> 4 -> 5
方案一:setTimeout 异步
for (var i = 0; i < 5; i++) {
;(function (j) {
setTimeout(function () {
console.log(new Date(), j)
}, 1000 * j) // 这里修改 0~4 的定时器时间
})(i)
}
setTimeout(function () {
// 这里增加定时器,超时设置为 5 秒
console.log(new Date(), i)
}, 1000 * i)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
方案二:promise 异步
const tasks = [] // 这里存放异步操作的 Promise
const output = (i) =>
new Promise((resolve) => {
setTimeout(() => {
console.log(new Date(), i)
resolve()
}, 1000 * i)
})
// 生成全部的异步操作
for (var i = 0; i < 5; i++) {
tasks.push(output(i))
}
// 异步操作完成之后,输出最后的 i
Promise.all(tasks).then(() => {
setTimeout(() => {
console.log(new Date(), i)
}, 1000)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
3:ES7
改进一:async/await
// 模拟其他语言中的 sleep,实际上可以是任何异步操作
const sleep = (timeountMS) =>
new Promise((resolve) => {
setTimeout(resolve, timeountMS)
})
;(async () => {
// 声明即执行的 async 函数表达式
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)
})()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
