关于for循环,await,事件循环的一些杂谈

/**
 * 我要实现一个需求
 * 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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值