资讯专栏INFORMATION COLUMN

JS setTimeout时间

张迁 / 502人阅读

摘要:所以根据不同的,在时间轴上定义匿名函数。当然,由于匿名函数指向的是全局变量,此时主执行结束早已为,所以弹出。

A

for (var i=5; i>=1; i--) { 
      setTimeout( function timer() {
          document.write(i+"
"); }, i*3000 ); } // 0 0 0 0 0 // 保存执行后,3秒后弹出第一个console(0),之后隔3秒弹出第二个,依次按照时间执行。

B

 for (var i=5; i>=1; i--) { 
      setTimeout( function timer() {
          document.write(i+"
"); }, 3000 ); } // 0 0 0 0 0 // 保存执行后,3秒后所有的console一齐弹出

C

 for (var i=5; i>0; i--) { 
          !function (i) {
              setTimeout( function timer() {
                console.log(i);
              }, i*3000 );
          }(i)
    }
   // 1 2 3 4 5 每隔3秒依次弹出
   
   
这里我抽象一下setTimeout的队列执行结构:

注意,时间设定与闭包没有关系!

当所有的非队列结构代码都执行完毕,函数调用栈清空后,这些setTimeout才会进入队列数据栈等待执行
。而时间,就是按照图中那样:

A:

A与B的区别就是时间i*30003000的区别。

setTimeout定义是与正常的JS执行是同步的,而函数的执行是异步的,所以,根据不同的i值,setTiemout在时间轴上已经定义了函数。
而且可以发现,时间设置里的i是根据for循环变化的(5 4 3 2 1),这也反证了setTimeout的定义时是与主JS程序同步。所以根据不同的i*3000,在时间轴上定义匿名函数。执行时,每隔3秒,弹出一个0。
当然,由于匿名函数指向的是全局变量i,此时主JS执行结束早已为0,所以弹出0。

B:

在B代码中,没有设置i与时间的计算,所以循环中产生的5个匿名函数都是定义在3秒这个时间节点上,当主JS代码执行完毕,开始执行队列结构栈中的函数时,5个函数在3秒后同时执行,所以会弹出5个0。而对于匿名函数中的i取值,这里自然是来自全局变量中的i,主JS程序执行完毕i自然运算完毕值为0,所以5个i都是0;

C:

引入闭包的情况和B其实是类似的,时间设定与匿名函数执行始终井水不犯河水,所以时间轴与B相同,不同的是匿名函数里的i值。
图中嵌套的正方形就抽象为自调用函数,每一次的循环中产生的i值,会传入自调用函数,保存在其变量对象中。由于匿名函数里的是自调用函数的闭包匿名函数引用了变量对象里的i,所以每个自调用函数的变量对象不会在执行完毕后被回收,得以保持继续被匿名函数引用着。最后实现最终效果。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/87066.html

相关文章

  • 解析setTimeout时间设置为0

    摘要:要是当前代码耗时很长,有可能要等很久,所以并没有办法保证,回调函数一定会在指定的时间执行。需要监听文字改变,每一次改变都会调用一次回调函数,现在需要的一种实现是在用户停止键盘事件一段时间后,去发送一个请求。 1、开胃菜,setTimeout为何物 首先看一下w3school上面对于setTimeout的解释 setTimeout(fn,millisec) 方法用于在指定的毫秒数后调用函...

    zhigoo 评论0 收藏0
  • JS单线程与setTimeout执行原理

    摘要:引擎单线程机制首先明确,引擎是单线程机制。是单线程执行的,无法同时执行多段代码。解析是单线程的,所以会先执行再,但这个循环体是死循环,所以永远不会执行。 Javascript 引擎单线程机制 首先明确,JavaScript引擎是单线程机制。 JavaScript 是单线程执行的,无法同时执行多段代码。当某一段代码正在执行的时候,所有后续的任务都必须等待,形成一个任务队列。一旦当前任务...

    tabalt 评论0 收藏0
  • JS代码在nodejs环境下执行机制和事件循环

    摘要:开始执行文件,同步代码执行完毕后,进入事件循环。时间未到的时候,如果有事件返回,就执行该事件注册的回调函数。对于多次执行输出结果不同,需要了解事件循环的基础问题。 1. 说明 nodejs是单线程执行的,同时它又是基于事件驱动的非阻塞IO编程模型。这就使得我们不用等待异步操作结果返回,就可以继续往下执行代码。当异步事件触发之后,就会通知主线程,主线程执行相应事件的回调。 本篇文章讲解n...

    Lowky 评论0 收藏0
  • javascript引擎执行的过程的理解--执行阶段

    摘要:如果对语法分析和预编译,还有疑问引擎执行的过程的理解语法分析和预编译阶段。参与执行过程的线程分别是引擎线程也称为内核,负责解析执行脚本程序的主线程例如引擎。以上便是引擎执行宏任务的整个过程。 一、概述 js引擎执行过程主要分为三个阶段,分别是语法分析,预编译和执行阶段,上篇文章我们介绍了语法分析和预编译阶段,那么我们先做个简单概括,如下: 1、语法分析: 分别对加载完成的代码块进行语法...

    SnaiLiu 评论0 收藏0
  • javascript引擎执行的过程的理解--执行阶段

    摘要:如果对语法分析和预编译,还有疑问引擎执行的过程的理解语法分析和预编译阶段。参与执行过程的线程分别是引擎线程也称为内核,负责解析执行脚本程序的主线程例如引擎。以上便是引擎执行宏任务的整个过程。一、概述 js引擎执行过程主要分为三个阶段,分别是语法分析,预编译和执行阶段,上篇文章我们介绍了语法分析和预编译阶段,那么我们先做个简单概括,如下: 1、语法分析: 分别对加载完成的代码块进行语法检验,语...

    Achilles 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<