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 相关文章推荐
菜单效果
Oct 14 Javascript
JQuery中的ready函数冲突的解决方法
May 17 Javascript
JavaScript判断变量是否为空的自定义函数分享
Jan 31 Javascript
跟我学习javascript的函数调用和构造函数调用
Nov 16 Javascript
jQuery使用zTree插件实现树形菜单和异步加载
Feb 25 Javascript
基于socket.io+express实现多房间聊天
Mar 17 Javascript
浅谈JavaScript前端开发的MVC结构与MVVM结构
Jun 03 Javascript
Vue学习笔记进阶篇之多元素及多组件过渡
Jul 19 Javascript
jQuery实现基本隐藏与显示效果的方法详解
Sep 05 jQuery
浅谈layer的Icon样式以及一些常用的layer窗口使用方法
Sep 11 Javascript
Node.js API详解之 tty功能与用法实例分析
Apr 27 Javascript
vue绑定数字类型 value为数字的实例
Aug 31 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备份数据库生成SQL文件并下载的函数代码
2012/02/05 PHP
PHP中date与gmdate的区别及默认时区设置
2014/05/12 PHP
ThinkPHP字符串函数及常用函数汇总
2014/07/18 PHP
PHP使用正则表达式获取微博中的话题和对象名
2015/07/18 PHP
PHP与Ajax相结合实现登录验证小Demo
2016/03/16 PHP
thinkPHP分组后模板无法加载问题解决方法
2016/07/12 PHP
php如何执行非缓冲查询API
2016/07/22 PHP
JavaScript 学习笔记之一jQuery写法图片等比缩放以及预加载
2012/06/28 Javascript
js添加select下默认的option的value和text的方法
2014/10/19 Javascript
CascadeView级联组件实现思路详解(分离思想和单链表)
2016/04/12 Javascript
jQuery Raty 一款不错的星级评分插件
2016/08/24 Javascript
JS判断鼠标进入容器的方向与window.open新窗口被拦截的问题
2016/12/23 Javascript
深入理解Angularjs向指令传递数据双向绑定机制
2016/12/31 Javascript
JS实现京东首页之页面顶部、Logo和搜索框功能
2017/01/12 Javascript
Bootstrap的popover(弹出框)2秒后定时消失的实现代码
2017/02/27 Javascript
jQuery zTree 异步加载添加子节点重复问题
2017/11/29 jQuery
Angular服务Request异步请求的实例讲解
2018/08/13 Javascript
vue 手机物理监听键+退出提示代码
2020/09/09 Javascript
Python实现比较两个列表(list)范围
2015/06/12 Python
Python中对元组和列表按条件进行排序的方法示例
2015/11/10 Python
HTML5 canvas实现移动端上传头像拖拽裁剪效果
2016/03/14 HTML / CSS
解决HTML5中的audio在手机端和微信端的不能自动播放问题
2019/11/04 HTML / CSS
Dyson戴森波兰官网:Dyson.pl
2019/08/05 全球购物
办公室保洁员岗位职责
2013/12/02 职场文书
给领导的致歉信范文
2014/01/13 职场文书
老师的检讨书
2014/02/23 职场文书
环保建议书
2014/03/12 职场文书
不服从上级领导安排的检讨书
2014/09/14 职场文书
我的职业生涯规划:打造自己的运动帝国
2014/09/18 职场文书
见习报告格式范文
2014/11/08 职场文书
2015年保卫科工作总结
2015/05/14 职场文书
消防安全主题班会
2015/08/12 职场文书
详解Vue的sync修饰符
2021/05/15 Vue.js
Nginx配置Https安全认证的实现
2021/05/26 Servers
十大好看的穿越动漫排名:《瑞克和莫蒂》第一,国漫《有药》在榜
2022/03/18 日漫
Win11 引入 Windows 365 云操作系统,适应疫情期间混合办公模式:启动时直接登录、模
2022/04/06 数码科技