JavaScript中EventLoop介绍


Posted in Javascript onJanuary 22, 2018

JavaScript中EventLoop介绍

想象下,比如浏览器在运行一个复杂的图像转换算法,因为是单线程的,所以此时浏览器进程被阻塞了,不能进行界面渲染,也不能运行其他代码,你的应用界面会失去和用户的交互。

这一般情况下还不会有大问题,但是当浏览器在同时运行多个类似的算法时,这个问题就很严重了。

有一定经验js开发人员大多都理解代码的异步执行,特别是ajax的使用。

// ajax(..) is some arbitrary Ajax function given by a library
var response = ajax('https://example.com/api');
console.log(response);
// `response` won't have the response

这里response 将不会得到你想要的结果。

而是需要像相面这样,通过 callback函数的方式,获取结果

ajax('https://example.com/api', function(response) {
  console.log(response); // `response` is now available
});

另外这里面提醒一下,下面的代码, async: false永远都不是一个好主意。

// This is assuming that you're using jQuery
jQuery.ajax({
  url: 'https://api.example.com/endpoint',
  success: function(response) {
    // This is your callback.
  },
  async: false // And this is a terrible idea
});

通过上面的例子,我们应该理解通过 异步 函数,可以帮助我们解决 类似浏览器阻塞问题。

当然还可以通过 setTimeout(callback, milliseconds)实现同样的逻辑。如果你理解了异步,下面代码执行会输出什么呢?

function first() {
  console.log('first');
}
function second() {
  console.log('second');
}
function third() {
  console.log('third');
}
first();
setTimeout(second, 1000); // Invoke `second` after 1000ms
third();

那个这下异步处理机制的原理是什么呢?这里就要引入我们的事件循环Event Loop了

JavaScript中EventLoop介绍

Event Loop有一个简单的Job(task) - 监视Call Stack和Callback Queue。如果调用堆栈为空,它将从队列中取出第一个事件,并将其推送到调用堆栈,从而有效地运行它。

这种迭代在事件循环中被称为Tick。每个事件只是一个函数回调。

console.log('Hi');
setTimeout(function cb1() { 
  console.log('cb1');
}, 5000);
console.log('Bye');

执行这段代码,下面的调用栈清楚的演示了事件循环的处理流程。

JavaScript中EventLoop介绍

请注意,setTimeout(...)不会自动将您的回调放在事件循环队列中。

它设置了一个计时器。当计时器到期时,浏览器将你的回调放到事件循环中,以便将来的一些tick会执行。但是,队列中可能还有其他事件已经被添加了 - 您的回调将不会立即执行。

有很多关于开始使用JavaScript中的异步代码的文章和教程,建议您使用setTimeout(callback,0)。
现在你知道Event Loop是怎么做的,以及setTimeout是如何工作的。

你就能更好的理解下面的代码

console.log('Hi');
setTimeout(function() {
  console.log('callback');
}, 0);
console.log('Bye');

尽管等待时间设置为0 ms,但浏览器控制台中的结果如下所示:

Hi

Bye

callback

Javascript 相关文章推荐
基于jquery的动态创建表格的插件
Apr 05 Javascript
ajax 同步请求和异步请求的差异分析
Jul 04 Javascript
解析javascript 浏览器关闭事件
Jul 08 Javascript
js自动生成的元素与页面原有元素发生堆叠的解决方法
Oct 24 Javascript
jquery中的ajax方法怎样通过JSONP进行远程调用
May 04 Javascript
DIV+CSS+jQ实现省市联动可扩展
Jun 22 Javascript
浅谈JavaScript中变量和函数声明的提升
Aug 09 Javascript
jquery实现的table排序功能示例
Mar 10 Javascript
详解微信图片防盗链“此图片来自微信公众平台 未经允许不得引用”的解决方案
Apr 04 Javascript
vue-cli脚手架打包静态资源请求出错的原因与解决
Jun 06 Javascript
Node.js安装详细步骤教程(Windows版)详解
Sep 01 Javascript
基于Element的组件改造的树形选择器(树形下拉框)
Feb 27 Javascript
element 结合vue 在表单验证时有值却提示错误的解决办法
Jan 22 #Javascript
基于vue2.x的电商图片放大镜插件的使用
Jan 22 #Javascript
vue 项目常用加载器及配置详解
Jan 22 #Javascript
详解vue+vuex+koa2开发环境搭建及示例开发
Jan 22 #Javascript
jquery+ajaxform+springboot控件实现数据更新功能
Jan 22 #jQuery
bootstrap+jquery项目引入文件报错的解决方法
Jan 22 #jQuery
angular写一个列表的选择全选交互组件的示例
Jan 22 #Javascript
You might like
PHP如何透过ODBC来存取数据库
2006/10/09 PHP
php不用正则采集速度探究总结
2008/03/24 PHP
php中fgetcsv()函数用法实例
2014/11/28 PHP
PHP身份证校验码计算方法
2016/08/10 PHP
PHP编程中的Session阻塞问题与解决方法分析
2017/08/07 PHP
PHP示例演示发送邮件给某个邮箱
2019/04/03 PHP
php根据地址获取百度地图经纬度的实例方法
2019/09/03 PHP
PHP调用接口API封装的例子
2019/10/11 PHP
Laravel框架处理用户的请求操作详解
2019/12/20 PHP
Thinkphp 框架扩展之类库扩展操作详解
2020/04/23 PHP
安装PHP扩展时解压官方 tgz 文件后没有configure文件无法进行配置编译的问题
2020/08/26 PHP
window.open的功能全解析
2006/10/10 Javascript
扩展javascript的Date方法实现代码(prototype)
2010/11/20 Javascript
JS解析json数据并将json字符串转化为数组的实现方法
2012/12/25 Javascript
jQuery自定义添加"$"与解决"$"冲突的方法
2015/01/19 Javascript
基于AngularJS实现页面滚动到底自动加载数据的功能
2015/10/16 Javascript
学习JavaScript正则表达式
2015/11/13 Javascript
封装属于自己的JS组件
2016/01/27 Javascript
用jquery获取自定义的标签属性的值简单实例
2016/09/17 Javascript
arcgis for js 修改infowindow样式的方法
2016/11/02 Javascript
jQuery实现ToolTip元素定位显示功能示例
2016/11/23 Javascript
javascript按钮禁用和启用的效果实例代码
2017/10/29 Javascript
js实现点击上传图片并设为模糊背景
2020/08/02 Javascript
Python实现检测服务器是否可以ping通的2种方法
2015/01/01 Python
使用Python的PEAK来适配协议的教程
2015/04/14 Python
Python内置函数——__import__ 的使用方法
2017/11/24 Python
利用Pandas 创建空的DataFrame方法
2018/04/08 Python
python3使用Pillow、tesseract-ocr与pytesseract模块的图片识别的方法
2020/02/26 Python
python实现银行账户系统
2021/02/22 Python
意大利单身交友网站:Meetic
2020/07/12 全球购物
高级电工工作职责
2013/11/21 职场文书
英语教师求职信
2014/06/16 职场文书
党员个人对照检查材料
2014/10/01 职场文书
安全生产警示教育活动总结
2015/05/09 职场文书
SpringBoot2 参数管理实践之入参出参与校验的方式
2021/06/16 Java/Android
python_tkinter弹出对话框创建
2022/03/20 Python