资讯专栏INFORMATION COLUMN

JavaScript的setTimeout和setInterval的深入理解

myeveryheart / 374人阅读

摘要:所以其实和所谓的异步调用事实上是通过将代码段插入到代码的执行队列中实现的。当执行和的时候,会根据你设定的时间准确地找到代码的插入点。综上所述,其实终归是单线程产物。无论如何异步都不可能突破单线程这个障碍。

发表过一片博客《跟着我用JavaScript写计时器》,比较基础.....有网友说应该写一下setTimeout的原理和机制,嗯,今天就来写一下吧:

直奔主题:setTimeout和setInterval是如何工作的呢?

我们知道,js是单线程执行的(单线程j就是说在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行)。所以其实setTimeout和setInterval所谓的“异步调用”事实上是通过将代码段插入到代码的执行队列中实现的。
而如何计算插入的时间点呢?自然是要用到我们所说的timer,也就是计时器。当执行setTimeout和setInterval的时候,timer会根据你设定的时间“准确”地找到代码的插入点。当队列“正常”地执行到插入点时,就触发timer callback,也就是我们设定的回调函数:

 
function fn() { 
/* 
here is some codes 
*/ alert("javascript");
setTimeout(function() {alert("ok!")},1000); 
} 
onload=fn;

上面这个例子就是我们通常的用法,应该容易理解。可是,timer真的能那么准确么?代码队列的执行真的能那么正常么?

还记得吗?重新认识所谓的“异步”

刚刚已经知道,事实上setTimeout和setInterval只是简简单单地通过插入代码到代码队列来实现代码的延迟执行(或者说异步执行)。但是事实上所谓的异步只是一个假象——它同样运行在一个线程上! 始终是单线程!
那么问题就来了,要是在代码插入点前的代码执行时间超过了传入setTimeout或setInterval的设定时间会怎样呢?让我们来看看这段代码:

 
function fn() { 
setTimeout(function(){alert("can you see me?");},1000); 
while(true) {} 
} 

你觉得这段代码的执行结果是什么呢?答案是,alert永远不会出现。

这是为什么呢?因为,while这段代码没有执行完(如图,浏览器一直在解析while的代码),所以插入在后面的代码便永远不会执行。
综上所述,其实JS终归是单线程产物。无论如何“异步”都不可能突破单线程这个障碍。所以许多的“异步调用”(包括Ajax)事实上也只是“伪异步”而已。只要理解了这么一个概念,也许理解setTimeout和setInterval也就不难了。

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

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

相关文章

  • JavaScriptsetTimeoutsetInterval深入理解

    摘要:所以其实和所谓的异步调用事实上是通过将代码段插入到代码的执行队列中实现的。当执行和的时候,会根据你设定的时间准确地找到代码的插入点。综上所述,其实终归是单线程产物。无论如何异步都不可能突破单线程这个障碍。 发表过一片博客《跟着我用JavaScript写计时器》,比较基础.....有网友说应该写一下setTimeout的原理和机制,嗯,今天就来写一下吧: 直奔主题:setTimeout和...

    cgh1999520 评论0 收藏0
  • JS 异步实现

    摘要:由于引擎同一时间只执行一段代码这是由单线程的性质决定的,所以每个代码块阻塞了其它异步事件的进行。这意味着浏览器将等待着一个新的异步事件发生。异步的任务执行的顺序是不固定的,主要看返回的速度。 我们经常说JS是单线程的,比如node.js研讨会上大家都说JS的特色之一是单线程的,这样使JS更简单明了,可是大家真的理解所谓JS的单线程机制吗?单线程时,基于事件的异步机制又该当如何,这些知识...

    sihai 评论0 收藏0
  • 理解javascript事件循环(Event Loop)

    摘要:主线程会暂时存储等异步操作,直接向下执行,当某个异步事件触发时,再通知主线程执行相应的回调函数,通过这种机制,避免了单线程中异步操作耗时对后续任务的影响。 背景 在研究js的异步的实现方式的时候,发现了JavaScript 中的 macrotask 和 microtask 的概念。在查阅了一番资料之后,对其中的执行机制有所了解,下面整理出来,希望可以帮助更多人。 先了解一下js的任务执...

    mykurisu 评论0 收藏0
  • setTimeout-setInterval看JS线程

    摘要:提出标准,允许脚本创建多个线程,但是子线程完全受主线程控制,且不得操作。所以,这个新标准并没有改变单线程的本质。事件循环主线程线程只会做一件事,就是从消息队列里面取消息执行消息,再取消息再执行。工作线程是生产者,主线程是消费者。 最近项目中遇到了一个场景,其实很常见,就是定时获取接口刷新数据。那么问题来了,假设我设置的定时时间为1s,而数据接口返回大于1s,应该用同步阻塞还是异步?我们...

    elliott_hu 评论0 收藏0
  • setTimeout深入JavaScript执行环境异步机制

    摘要:图片转引自的演讲和两个定时器中回调的执行逻辑便是典型的机制。异步编程关于异步编程我的理解是,在执行环境所提供的异步机制之上,在应用编码层面上实现整体流程控制的异步风格。 问题背景 在一次开发任务中,需要实现如下一个饼状图动画,基于canvas进行绘图,但由于对于JS运行环境中异步机制的不了解,所以遇到了一个棘手的问题,始终无法解决,之后在与同事交流之后才恍然大悟。问题的根节在于经典的J...

    codeGoogle 评论0 收藏0

发表评论

0条评论

myeveryheart

|高级讲师

TA的文章

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