博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
事件驱动模型
阅读量:5926 次
发布时间:2019-06-19

本文共 1197 字,大约阅读时间需要 3 分钟。

从setTimeout说起

这是一个JS引擎当中内置的定时器函数
官方的定义如下

setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式

但是实践证明 , 即使是setTimeout(fn, 0)

fn函数也不会立即被执行
例如下列代码

console.log(1);var timeFunc = function(){    console.log(2);}setTimeout(timeFunc,0);console.log(3);
执行的结果是1 3 2 , 而不是1 2 3

JS引擎的单线程特性

JS语言设计的一个很重要的特点就是 : JS是没有多线程的

但是JS引擎是单线程 , 浏览器却可以是多线程 , JS引擎只是浏览器的一个线程而已
定时器 网络请求 浏览器渲染等操作 , 都是由不同的线程去完成的
比如下面这个例子

var isEnd = true;window.setTimeout(function () {    isEnd = false;    }, 1000);while (isEnd);console.log('end');

 

在1s之后 , 将isEnd置为false , 表面看来后面的死循环只会持续1s而已

但是实际上这段代码会一直陷入死循环
这也证明了setTimeout并不能实现多线程


JS是基于事件驱动的语言 , 它的执行顺序遵循事件队列的机制 

浏览器有各种各样的线程 , 这些线程的联系都是基于事件的 , 当JS引擎处理到与其他线程相关的代码 , 就会分发到其他的线程

在这个过程中 , JS引擎并不会阻塞自己的线程等待其他线程执行完毕 , 而且其他线程执行完毕后添加事件任务告诉js引擎执行相关操作 , 这就是js的异步编程模型.

拿上面的定时器函数来说 , 执行这个函数的时候 , 就会开启一个定时器线程( 注意: 这个线程并不属于JS引擎 ) , 这个线程会在指定时间后向事件队列中添加一个任务 , 这个任务就是执行传递给setTimeout的函数

既然是队列 , 后入队的任务当然会在主线程的任务之后执行

如果主线程的任务一直不结束 , 那么这个队列就会一直阻塞

这同样也可以解释同步ajax请求 , 当后台响应较慢的时候造成的页面假死现象
页面要与用户进行交互 , 依靠的是响应事件 , 比如鼠标点击事件等
但是主线程任务一直不结束 , 点击事件的任务只能在后面排队 , 事件方法不会被执行 , 当然就有了假死现象
当主线程任务结束的时候 , 这些事件方法仍然会执行

由此可见官方对于settimeout的定义是有迷惑性的.应该给一个新的定义:

在指定时间内, 将任务放入事件队列,等待js引擎空闲后被执行.

转载于:https://www.cnblogs.com/programInit/p/6363183.html

你可能感兴趣的文章
项目管理学习笔记之二.工作分解
查看>>
Linux系统启动流程详解
查看>>
通过源码解析 Node.js 中一个 HTTP 请求到响应的历程
查看>>
CodeIgniter的密码处理论
查看>>
Spring Cloud Config服务器
查看>>
测试人员必学的软件快速测试方法(二)
查看>>
Agora iOS SDK-快速入门
查看>>
引入间接隔离变化(三)
查看>>
统一沟通-技巧-4-让国内域名提供商“提供”SRV记录
查看>>
cocos2d-x 3.0事件机制及用户输入
查看>>
比亚迪速锐F3专用夏季座套 夏天坐垫 四季坐套
查看>>
C++ 数字转换为string类型
查看>>
程序员全国不同地区,微信(面试 招聘)群。
查看>>
【干货】界面控件DevExtreme视频教程大汇总!
查看>>
闭包 !if(){}.call()
查看>>
python MySQLdb安装和使用
查看>>
Java小细节
查看>>
poj - 1860 Currency Exchange
查看>>
chgrp命令
查看>>
Java集合框架GS Collections具体解释
查看>>