setTimeout、同步、异步的理解
console.log('111');
setTimeout(()=>{
console.log('222')
},1000);
console.log('333');
setTimeout(()=>{
console.log('444')
},0);
console.log(555);
就是执行这样一段js代码 , 打印出来的结果是 :
111 -> 333 -> 555 -> 444 -> 222
(结果就是我们理论起来 setTimeout 到底是同步还是异步的 ?为什么会这样执行 ? JavaScript不是一门单线程的语言吗?)
了解setTimeout 与 clearTimeout
setTimeout 接受两个参数,第一个是包含js代码的字符串和函数,第二个参数是等待多长时间的毫秒数,但经过该事件指定的代码不一定执行(下面讲解缘由)。clearTimeout 接受一个setTimeout 返回的id 值作为参数传递给它,取消代码的执行。
//设置超时调用
var timeoutId = setTimeout(function (){
alert("hello World");
},1000);
//取消掉用的代码
clearTimeout(timeoutId);
JavaScript中没有任何代码是立即执行的,但是只用进程一旦空闲就会立即执行,所以题目中设置的事件不过是经过多少毫秒数被添加到了队列中,而不是经过多少时间后就被执行。
在这里,我们需要有一点进程,线程的知识来支撑我们理解js中同步,异步的编程思想
众所周知,javascript是一门单线程的语言,即在js引擎中负责解释和执行js代码的线程只能有一个,但是,我们知道浏览器是多线程的。html5中提出了新的web标准,允许javascript 脚本创建多个线程,但子线程完全受主线程控制,且不得进行Dom操作,因此也并没有改变单线程的本质。
同步异步的理解
同步:假如一个函数返回时,调用者就能够得到预期结果(拿到了预期的返回值或者看到了预期的效果),这就是同步函数。
alert("hello World");
console.log("hello World");
异步:调用一个函数,返回的值不是预期的结果,需要通过一定的手段才能得到预期的返回值,这就是异步函数
var timeoutId = setTimeout(function (){
alert("hello World");
},1000)
异步执行的过程:
主线程发起一个异步请求,相应的工作线程(比如浏览器的其他线程)接收请求并告知主线程已收到(异步函数返回);主线程可以继续执行后面的代码,同时工作线程执行异步任务;工作线程完成工作后,通知主线程;主线程收到通知后,执行一定的动作(调用回调函数)。(工作线程将消息放到消息队列中,主线程通过时间循环去逐个取信息,)
发起函数 – 发起异步过程
回调函数 – 返回处理结果
事件循环的机制
主线程只会做一件事,就是从消息队列里面取消息、执行消息。当消息队列为空时,就会等待消息队列变成非空。只有当前的消息执行结束,才会去取下一个消息。这种机制就叫做事件循环机制Event Loop,取一个消息并执行的过程叫做一次循环。
setTimeout 函数的解决
在了解了以上的知识点后,我们就能够对setTimeout 函数有很好的理解,在执行我们本页开始的代码的时候,先在控制台输出 one ,然后主线程发起异步请求,工作线程接受请求,将setTimeout 经过设置的时间数推入消息队列,最终通过事件循环取出消息进行调用,这就是我们刚才开始看到结果的原因了。
setTimeout 到底是同步还是异步的 ?
除了放置异步任务的事件,"任务队列"还可以放置定时事件。
setTimeout()接受两个参数,第一个是回调函数,第二个是推迟执行的毫秒数。
需要注意的是,setTimeout()只是将事件插入了"任务队列",必须等到当前代码(执行栈)执行完,主线程才会去执行它指定的回调函数。要是当前代码耗时很长,有可能要等很久,所以并没有办法保证,回调函数一定会在setTimeout()指定的时间执行。
综上所属
setTimeout是单线程,类似异步,但不是异步 。
setTimeout、同步、异步的理解的更多相关文章
- 关于vue生命周期中的同步异步的理解
在vue官网中介绍生命周期的图如下: 主要测试代码如下: 主要是测试前四个生命周期beforeCreate,created,beforeMount,mounted,里面同步和异步的执行顺序,其它的类似 ...
- java 关于同步异步的理解
经常看到介绍 ArrayList 和HashMap是异步,Vector和HashTable是同步,这里同步是线程安全的,异步不是线程安全的,举例说明: 当创建一个Vector对象时候, Vector ...
- AJAX中的请求方式以及同步异步的区别
AJAX中的请求方式以及同步异步的区别请求方式,分为GET与POST: GET 最为常见的HTTP请求,普通上网浏览页面就是GET.GET方式的参数请求直接跟在URL后,以问号开始.(JS中用wind ...
- Java中线程同步的理解 - 其实应该叫做Java线程排队
Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可 ...
- jquery ajax 同步异步的执行
jquery ajax 同步异步的执行 大家先看一段简单的jquery ajax 返回值的js 代码 function getReturnAjax{ $.ajax({ type:" ...
- java中线程同步的理解(非常通俗易懂)
转载至:https://blog.csdn.net/u012179540/article/details/40685207 Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运 ...
- js中对同步和异步的理解
你应该知道,javascript语言是一门“单线程”的语言,不像java语言,类继承Thread再来个thread.start就可以开辟一个线程,所以,javascript就像一条流水线,仅仅是一条流 ...
- JS中同步与异步的理解
你应该知道,javascript语言是一门“单线程”的语言,不像java语言,类继承Thread再来个thread.start就可以开辟一个线程,所以,javascript就像一条流水线,仅仅是一条流 ...
- Netty基础系列(2) --彻底理解阻塞非阻塞与同步异步的区别
引言 在进行I/O学习的时候,阻塞和非阻塞,同步和异步这几个概念常常被提及,但是很多人对这几个概念一直很模糊.要想学好Netty,这几个概念必须要掌握清楚. 同步和异步 同步与异步的区别在于,异步基于 ...
随机推荐
- Java知识系统回顾整理01基础02面向对象02属性
一.根据实例给出"属性"的定义 一个英雄有姓名,血量,护甲等等状态 这些状态就叫做一个类的属性 二.属性的类型 属性的类型可以是基本类型,比如int整数,float 浮点数 也可以 ...
- VSCode搭建golang环境
安装对应版本的Golang 略 VSCode安装对应 Go 插件 在应用商店安装即可:go VSCode安装 Go 工具: 在VSCode输入:Crtl + Shift + P 在弹出框输入:inst ...
- try with resource当中你没有注意到点。。
怎么使用try with resource语法 在 JDK 9 中更简洁使用 try-with-resources 语句 try with resource当中你没有注意到点 try with res ...
- Varnish 6.2.2 的介绍与安装
一.简介 Varnish 是一款高性能且开源的反向代理服务器和 HTTP 加速器,其采用全新的软件体系机构,和现在的硬件体系紧密配合,与传统的 Squid 相比,Varnish 具有性能更高.速度更快 ...
- Redis安装使用以及可能的算法实践
layout: post title: 2017-12-05-Redis 入门 tags: - Redis - 实时特征 - UCB, Tompson sampling Redis 是什么? Redi ...
- day35 Pyhton 网络编程02
一内容回顾 网络基础 网络应用开发架构 B/S架构 浏览器直接作为客户端的程序 C/S架构 B/S是特殊的C/S osi七层模型 应用层 python代码 http https ftp ...
- day19 Pyhton学习 递归函数
# 函数的递归 : 在一个函数的内部调用它自己 # import sys # sys.setrecursionlimit(1000000) # 设置递归的最大深度 # 总结 # 1.递归函数的定义 : ...
- docker设置http访问
1 编辑配置文件 vim /etc/docker/daemon.json { "registry-mirrors": ["https://a4fyjv0u.mirr ...
- centos 下安装redis 通过shell脚本
#! /bin/bash echo -e "开始安装redis服务\n" download_url=http://download.redis.io/releases/redi ...
- maven项目导入eclipse报错
错误提示: 原因:未安装maven,缺少ojdbc6.jar包 解决: 一.安装maven 第一步百度搜索Maven官网,进去之后,下载apache-maven-3.5.3-bin.zip,下载完成之 ...