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下通过$.browser来判断浏览器.
Apr 05 Javascript
js和jquery使按钮失效为不可用状态的方法
Jan 26 Javascript
JavaScript更改原始对象valueOf的方法
Mar 19 Javascript
6种javascript显示当前系统时间代码
Dec 01 Javascript
jQuery DataTables插件自定义Ajax分页实例解析
Apr 28 Javascript
Vue的路由动态重定向和导航守卫实例
Mar 17 Javascript
浅谈vue项目4rs vue-router上线后history模式遇到的坑
Sep 27 Javascript
jQuery+css last-child实现选择最后一个子元素操作示例
Dec 10 jQuery
Django+Vue实现WebSocket连接的示例代码
May 28 Javascript
通过vue写一个瀑布流插件代码实例
Sep 07 Javascript
如何利用 JS 脚本实现网页全自动秒杀抢购功能
Oct 12 Javascript
Vue使用Ref跨层级获取组件的步骤
Jan 25 Vue.js
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 常用字符串函数总结
2008/03/15 PHP
Zend Studio去除编辑器的语法警告设置方法
2012/10/24 PHP
深入解析PHP的引用计数机制
2013/06/14 PHP
laravel5.6 框架邮件队列database驱动简单demo示例
2020/01/26 PHP
js substr支持中文截取函数代码(中文是双字节)
2013/04/17 Javascript
两个select多选模式的选项相互移动(示例代码)
2014/01/11 Javascript
JS根据变量保存方法名并执行方法示例
2014/04/04 Javascript
input输入框鼠标焦点提示信息
2015/03/17 Javascript
深入浅出理解javaScript原型链
2015/05/09 Javascript
在浏览器中打开或关闭JavaScript的方法
2015/06/03 Javascript
初识Javascript小结
2015/07/16 Javascript
JQuery和PHP结合实现动态进度条上传显示
2016/11/23 Javascript
在点击div中的p时,如何阻止事件冒泡
2017/02/07 Javascript
Vue.js学习笔记之修饰符详解
2017/07/25 Javascript
js制作简单的音乐播放器的示例代码
2017/08/28 Javascript
ES7中利用Await减少回调嵌套的方法详解
2017/11/01 Javascript
vue.js-div滚动条隐藏但有滚动效果的实现方法
2018/03/03 Javascript
浅谈express.js框架中间件(middleware)
2019/04/07 Javascript
vue中 数字相加为字串转化为数值的例子
2019/11/07 Javascript
JavaScript代码压缩工具UglifyJS和Google Closure Compiler的基本用法
2020/04/13 Javascript
[42:24]完美世界DOTA2联赛循环赛 LBZS vs DM BO2第一场 11.01
2020/11/02 DOTA
零基础学Python(一)Python环境安装
2014/08/20 Python
Python中str is not callable问题详解及解决办法
2017/02/10 Python
对pandas中to_dict的用法详解
2018/06/05 Python
pyshp创建shp点文件的方法
2018/12/31 Python
matplotlib运行时配置(Runtime Configuration,rc)参数rcParams解析
2021/01/05 Python
Debenhams爱尔兰:英国知名的百货公司
2017/01/02 全球购物
如何用Java判断一个文件或目录是否存在
2012/11/19 面试题
连锁酒店店长职责范本
2014/02/13 职场文书
自查自纠工作情况报告
2014/10/29 职场文书
小学生光盘行动倡议书
2015/04/28 职场文书
2016年师德先进个人事迹材料
2016/02/29 职场文书
一文搞清楚MySQL count(*)、count(1)、count(col)区别
2022/03/03 MySQL
JavaScript实现外溢动态爱心的效果的示例代码
2022/03/21 Javascript
基于Apache Hudi在Google云构建数据湖平台的思路详解
2022/04/07 Servers
python读取并查看npz/npy文件数据以及数据显示方法
2022/04/14 Python