for + 异步请求同步执行问题
有个需求是循环请求一个接口获得数据,
问题是循环请求了但是接口是异步的,按顺序传过去的返回来的并不一定
按顺序返回来。
解法一——async await
1 | mounted() { |
解法二——Promise.all
利用Promise.all 顺序返回的特性
1 | mounted() { |
解法三 ——递归
1 | mounted() { |
间隔打印问题
要实现的功能:在for循环中写一个计时器,先隔2000毫秒打印1,再隔2000毫秒打印2….依次每间隔2000毫秒打印出0到9.
基本思路
要实现分别输出数组中的所有值,通过简单的for循环就能实现。要实现间隔一段时间输出,则使用setTimeout函数。
先写一个基本循环
1 | function test(){ |
可以在控制台看到紧跟着分别输出了小于10的i的值。
- 加上setTimeout加上setTimeout函数后,因为js执行机制和作用域问题,控制台的内容却都变成了10。
js 1
2
3
4
5
6
7
8function test(){
for (var i = 0; i < 10; i++) {
+ setTimeout(function(){
console.log(i);//分别输出i的值
+ },2000)
}
};
test();
解决方案一 ——闭包
终于来到了本文中最重要的一部分。什么是闭包?!
闭包是指有权访问另一个函数作用域中的变量的函数。或者说,将函数作为参数或者返回值。创建闭包的常见方式,就是在一个函数内部创建另一个函数。以下面的代码为例。
1 | function test(){ |
解决方案二——let
如下面的代码所示,使用let替换var,也能输出0-9的值。这是因为,当for循环中的i是通过var定义的变量时,作用域是一整个封闭函数,是全局作用域;当i是通过let定义的变量时,作用域在代码块中,叫做块级作用域,在for循环这个子块中。
1 | function test(){ |
最终方案:
闭包版本
1
2
3
4
5
6
7
8
9
10function test(){
for (var i = 0; i < 10; i++) {
(function(j){//闭包
setTimeout(function(){
console.log(j);//分别输出i的值
},2000*j)
})(i);//闭包
};
};
test();let 版本
1
2
3
4
5
6
7
8function test(){
for (let i = 0; i < 10; i++) {
setTimeout(function(){
console.log(i);//分别输出i的值
}, 2000 * i)
};
};
test();Promise版本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15const Print = (i) => {
return new Promise(resolve => {
setTimeout(function(){
resolve(i)
console.log(i)
}, 2000 )
})
}
async function test (){
for (var i = 0; i < 10; i++) {
await Print(i)
};
};
test();