javascript真的是异步的吗?且看setTimeout的实现原理以及setTimeout(0)的使用场景「建议收藏」

javascript真的是异步的吗?且看setTimeout的实现原理以及setTimeout(0)的使用场景

大家好,又见面了,我是全栈君。

在今天之前我一直以为setTimeout这个函数是异步的,无意中看到了一篇关于setTimeout的文章。发现自己曾经的认识全是错误的,赶紧总结下。


先看一段代码:

var start = new Date();
setTimeout(function(){
    var end = new Date();
    console.log("Time elapsed: ", end - start, "ms");
}, 500);

while (new Date - start <= 1000)
{

}

运行这段脚本能够看到:Time elapsed的值大概在1001ms左右,肯定会超过1000ms。也就是说:setTimeout失效了,指定的函数并没有在500ms后运行。而是延迟到1000ms后才运行。


再看一段代码:

function a()
{
	setTimeout(function(){console.log(1);},0);
	console.log(2);
}
a();

执行这段脚本能够看到:先打印2后打印1,我们在setTimeout里面指定了0ms,希望能马上执行,可是实际上没有效果。


想要理解上面的2段代码,我们得了解一下javascript中setTimeout的实现原理。首先牢记一点:JavaScript 是单线程运行的,也就是无法同一时候运行多段代码。

以下这段解释来自这篇博客

        JavaScript是单线程运行的,无法同一时候运行多段代码。当某一段代码正在运行的时候,全部兴许的任务都必须等待,形成一个队列。

一旦当前任务运行完毕,再从队列中取出下一个任务,这也常被称为 “堵塞式运行”。所以一次鼠标点击,或是计时器到达时间点,或是Ajax请求完毕触发了回调函数。这些事件处理程序或回调函数都不会马上运行,而是马上排队。一旦线程有空暇就运行。假如当前 JavaScript线程正在运行一段非常耗时的代码,此时发生了一次鼠标点击。那么事件处理程序就被堵塞。用户也无法马上看到反馈。事件处理程序会被放入任务队列。直到前面的代码结束以后才会開始运行。假设代码中设定了一个 setTimeout,那么浏览器便会在合适的时间。将代码插入任务队列。假设这个时间设为 0,就代表马上插入队列,但不是马上运行。仍然要等待前面代码运行完成。

所以 setTimeout 并不能保证运行的时间。是否及时运行取决于 JavaScript 线程是拥挤还是空暇。


也就是说setTimeout仅仅能保证在指定的时间过后将任务(须要运行的函数)插入队列等候,并不保证这个任务在什么时候运行。运行javascript的线程会在空暇的时候,自行从队列中取出任务然后运行它。javascript通过这样的队列机制。给我们制造一个异步运行的假象。

var start = new Date();
setTimeout(function(){
    var end = new Date();
    console.log("Time elapsed: ", end - start, "ms");
}, 500);

console.log("task finished.");

我们之所以会感觉到这段代码是在异步运行,这是由于javascript线程并没有由于什么耗时操作而堵塞,所以能够非常快地取出排队队列中的任务然后运行它。

如今我们知道了setTimeout的原理了,如今看下setTimeout(0)的使用场景。以下这个样例来自这篇文章

<input type="text" onkeydown="show(this.value)">
<div></div>
<script type="text/javascript">
  function show(val) {
    document.getElementsByTagName('div')[0].innerHTML = val;
  }
</script>

这里绑定了 keydown 事件,意图是当用户在文本框里输入字符时。将输入的内容实时地在 <div> 中显示出来。可是实际效果并不是如此,能够发现。每按下一个字符时,<div> 中仅仅能显示出之前的内容,无法得到当前的字符。

<input type="text" onkeydown="var self=this; setTimeout(function() {show(self.value)}, 0)">
<div></div>
<script type="text/javascript">
  function show(val) {
    document.getElementsByTagName('div')[0].innerHTML = val;
  }
</script>

这段代码使用了setTimeout(0)就能够实现需要的效果了。

这里事实上涉及2个任务,1个是将键盘输入的字符回写到输入框中。一个是获取文本框的值将其写入div中。第一个是浏览器自身的默认行为。一个是我们自己编写的代码。非常显然。必需要先让浏览器将字符回写到文本框。然后我们才干获取其内容写到div中。改变顺序,这这正是setTimeout(0)的作用。


參考文章:setTimeout(0) 的作用

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/116141.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 云计算与大数据技术应用 第四章课后答案_云计算原理与实践

    云计算与大数据技术应用 第四章课后答案_云计算原理与实践数据中心数据中心的概念数据中心,顾名思义就是数据的中心,是处理和存储海量数据的地方,英文全称为DataCenter。用专业的名词解释,数据中心是全球协作的特定设备网络,用来在internet网络基础设施上传递、加速、展示、计算、存储数据信息。尽管数据中心听起来神秘高大上,但按照最简单直接的理解,数据中心实际上就是我们个人电脑的扩大版,你的家用电脑就是你个人的数据中心。一般来讲,数据中心主要有几大部分构成:机房(建筑物本身)、供配电系统、制冷系统、网络设备、服务器设备、存储设备等。那数据中心的这些构成模

  • qt报错lnk2019_2019咬文嚼字十大错误

    qt报错lnk2019_2019咬文嚼字十大错误Qt错误:LNK2019:无法解析的外部符号原因及解决办法删除Qt中的一些用不到的函数或者添加一个新的.ui窗口的时候,我遇到了这个LINK2019无法解析的外部符号错误,网上查了半天可算解决了,写篇博客记录下。错误原因1:函数(一般是槽函数)在.h中声明,但却没有实现如图,我在自己的automatic.c文件中生成了一个按钮的点击处理函数,后面不想用了,把它删掉了,但是在automatic.h中忘记删掉声明了,于是系统编译报错。所以删掉声明就好。错误原因2:添加新的.ui窗体文件时编

  • java的二维数组讲解_javalambda表达式语法

    java的二维数组讲解_javalambda表达式语法1、二维数组概述1、二维数组其实就是一个特殊的一维数组,一维数组中每个元素就是一个一维数组2、三维数组又是一个特殊的二维数组2、二维数组的定义int[][]a=newint[10][10];String[][]b=newString[10][10];3、初始化二维数组//静态初始化int[][]a={{1,2,3,4},{4,5,6,7},{8,9,10,11}};//动态初始化

    2022年10月25日
  • springcloud和dubbo区别「建议收藏」

    springcloud和dubbo区别「建议收藏」最大区别SpringCloud抛弃了Dubbo的RPC通信,采用的是基于HTTP的REST方式。这两种方式各有优劣。虽然从一定程度上来说,后者牺牲了服务调用的性能,但也避免了上面提到的原生RPC带来的问题。而且REST相比RPC更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的强依赖,这在强调快速演化的微服务环境下,显得更加合适。…

  • 查看服务器并发连接数_查看数据库当前连接数

    查看服务器并发连接数_查看数据库当前连接数查看Sql Server当前的并发连接数

  • 用python做学生信息管理系统_python管理系统实例

    用python做学生信息管理系统_python管理系统实例Python面向对象版学员管理系统文章目录Python面向对象版学员管理系统目标一.系统需求二.准备程序文件2.1分析2.2创建程序文件三.书写程序3.1student.py3.1.2程序代码3.2managerSystem.py3.2.1定义类3.2.2管理系统框架3.3main.py3.4定义系统功能函数3.4.1添加功能3.4.2删除学员3.4.3修改学员信息3.4.5查询学员信息3.4.6显示所有学员信息3.4.7保存学员信息3.4.8加载学员信息四.总结

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号