/**
* 我要实现一个需求
* for循环五次
* 开始执行后,每隔一秒
* 我要打印出i 也就是 1 2 3 4 5,间隔一秒打印
*/
//要解决的问题1-------settimeout为宏任务,for循环为同步的
// 当for循环完后,i已经变成了5,那么最后五个定时器打印的都会是5
// for (var i = 0; i < 5; i++) {
// setTimeout(() => {
// console.log(i)
// }, 1000)
// }//---- 5 5 5 5 5
// 没有闭包,1000后打印五个5
// 那么如何解决这个问题呢 使用闭包 可以储存每次的i 这里就不用自执行函数
// 等等了,直接用es6的let,拥有块级作用域,可以存储每次的i
// for (let i = 0; i < 5; i++) {
// setTimeout(() => {
// console.log(i)
// }, 1000)
// } // 1 2 3 4 5 但是是同时打印出来的
// let可以闭包 闭包能拿到所有变量,但是它们都是1000之后打印出来,也就是五个定时器
// 同时等待一秒后执行,没有先后一秒执行
// 第二个问题是,如何间隔一秒打印
// 这里我有两种解决方案
// 一个是动态控制生成的定时器的时间
// for (let i = 1; i < 6; i++) {
// setTimeout(() => {
// console.log(i)
// }, i * 1000)
// } //实现了
// 还有一个是通过async await 可以使异步代码同步执行
// async function getI(i) {
// return new Promise((resolve, reject) => {
// setTimeout(() => {
// resolve(i)
// }, 1000);
// })
// }
// async function fuck() {
// for (let i = 1; i < 6; i++) {
// console.log(await getI(i))
// }
// }
// fuck()//实现了
// 可以得出几点
// 1.for循环的代码是同步执行的
// 也就是说,for循环不是宏任务,而是同步代码
// 打个比方 把上面代码拆解一下
// 块级作用域
// {
// let i = 1;
// setTimeout(() => {
// console.log(i)
// }, i * 1000)
// }
// {
// let i = 2;
// setTimeout(() => {
// console.log(i)
// }, i * 1000)
// }
// 。。。。。
// 显然它还是遵守事件循环规则
// 执行同步代码,微任务,渲染,又宏任务
// for循环拆开后就是上述代码的执行
// 就是普通的自上而下的代码执行罢了
// 不会阻塞
// 2.还有一个知识点,是这样的
// await接收到resolve结果 ,一般来说resolve的时候
// 就已经把pedding状态改为resolved或者rejected了,然后await才得到结果
// 但是如果resolve被定时器包起来了,那么这个状态的修改会在await得到结果之后
// 听说是这样的,没试过。。随便把
// 谈到await,我就不得不说点了
// async和await的作用不用我多说了
// 他们可以让异步代码同步执行,可以用await拿到异步的执行结果,同步执行
// await只能在async标识的函数中存在,
// await需要接受一个promise,它可以拿到这个promise resolve或者reject的结果
// 换言之,如果promise的状态一直pedding而没有执行resolve或者reject
// 来改变状态返回结果,那么此await便会一直阻塞
// 我在项目中也曾循环发过请求
// 之前是直接发送,没有用await async
// 后来觉得不太好,因为10个请求一起同时发送的
// 我希望能够一个个按顺序发送,所以用了await async
// 写法如下
// for (let i = 0; i < 10; i++) {
// await new Promise((resove, reject) => {
// // 这里只是随便举个不存在的请求例子
// webajax.getData.then(res => {
// if (res.code == 200) {
// resove(res.data)
// } else {
// reject(res.errMessage)
// }
// })
// })
// }
// for循环的具体拆解
// 每次都在{}代码块中声明i或者j,然后执行代码
// 在这种情况下,let和var产生了区别
// let能够和{}花括号形成块级作用域,实现闭包存储变量,
// 那么最终定时器存储了相应的j,打印 1 2,在外部也是打印不出j的,因为j是局部变量了
// 而var没有块级作用域,所以即使包了{}花括号,也相当于和直接写在外面没什么区别
// 所以没有实现闭包,外面也能打印出来i
// {
// var i = 1
// setTimeout(() => {
// console.log(i)
// }, 0);
// }
// {
// var i = 2
// setTimeout(() => {
// console.log(i)
// }, 0);
// }
// console.log(i)//2
// 实际上用var的话,上面代码和下面代码没区别
// var i = 1
// setTimeout(() => {
// console.log(i)
// }, 0);
// var i = 2
// setTimeout(() => {
// console.log(i)
// }, 0);
// console.log(i)//2
{
let j = 1
setTimeout(() => {
console.log(j)
}, 0);
}
{
let j = 2
setTimeout(() => {
console.log(j)
}, 0);
}
console.log(j)//j is not defined