前段的功能越来越强大,现在实现同步的for循环输出的方式也越来越多,我们先看一个例子:
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。
那么我们的解决办法有哪些呢?
先上一个es5以前的解决办法:
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;
下面开始用es6的方法实现啦!
1.用块作用域的let
forF();
function forF() {
for (let i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i);
}, 1000*i)
}
}
因为let是块作用域的,对于setTimeout函数而言,每次循环都新创建一个i,每个i不共享
2.await(其实是es7的)
见代码
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...
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的知识点百度也很多,可自行百度。
后续会更新,欢迎补充
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。