onpaste事件不生效_从实际开发中来看JavaScript事件循环的使用场景
前言: 本文是介绍结合DOM事件流和JavaScript事件循环解决一个工作中的实际问题的过程,很多东西不只是面试的时候才会用得到
文中涉及到的代码demo地址:drag-and-eventloop
背景
近期在开发某需求的时候,遇到了一个需要同时有拖拽和点击的场景,首席CV(复制粘贴)工程师如我 ,当然是使用react-draggable开源组件了,大概的代码结构(已脱敏)如下
import
但是,这样存在一个问题在拖拽完毕之后,拖拽区会响应一次点击事件,这是不合理也是不符合预期的。
梳理了一下react-draggable原理和业务代码的流程,整个过程可以总结为下图
因为react-draggable是使用mousedown和mouseup来实现拖拽的,而且并没有暴露出方法或者参数来处理mouseup之后同时会触发click事件的问题,所以只能我们自己处理这个问题了。
解法
标志位
我的方法是加一个canClick标志位,用来标识当前是否可以点击,在拖动时设置它为false,拖动结束时设置它为true
import
但是这样子依然不行,仔细思考之后发现这里会涉及到一些事件循环的原理,JavaScript是单线程语言,要实现非阻塞的去处理一些异步任务,就会把相关的异步回调放入到事件队列中,例如DOM事件回调这样的方法会被放入到宏事件(macroTask)队列中去,所以当前宏事件(macroTask)队列应该是这样的:
如上图,宏事件(macroTask)队列从左往右执行,在_handleDragStop方法中,已经把标志位canClick置为了true,所以在拖拽结束时,仍然是可以响应click事件的。
结合事件循环宏事件(macroTask)队列的执行,我们可以对代码做一些小修改,即可以达到目的:
import
此时,宏事件(macroTask)队列就变成了下图这样子
把设置canClick=true的语句放到setTimeout中,这样就把执行顺序放到了onClick事件回调的后面,标志位就开始生效了!
事件循环(eventLoop)
什么是事件循环?貌似这个概念只有在面试的时候会被问到,然后在面试完一周之内就会忘记,别笑,因为我之前面试也问过别人这个概念
事实上,理解事件循环的工作方式对于代码优化很重要,有时对于正确的架构也很重要。
概念
简单的说,事件循环(eventLoop)是单线程的JavaScript在处理异步事件时进行的一种循环过程,具体来讲,对于异步事件它会先加入到事件队列中挂起,等主线程空闲时会去执行事件队列中的事件。
宏事件(macroTask)队列和微事件(microTask)队列
因为异步事件种类的不同、执行优先级不同,不同的异步事件被分为宏任务和微任务。
常见的宏事件:
- setTimeout
- setInterval
- UI 事件
- 网络请求
- ....
常见的微事件
- Promise.resolve、Promise.reject
- Mutation Observer
- queueMicrotask(func)
宏任务和微任务的执行顺序是这样的:当前执行栈执行完毕时会立刻先处理所有微任务队列中的事件,然后再去宏任务队列中取出一个事件。同一次事件循环中,微任务永远在宏任务之前执行
事件循环的其他应用
拆分CPU过载任务
demo:intensiveCalculate.html
对于一些CPU耗时过长的任务,我们可以使用事件循环来拆分避免浏览器长时间不响应页面事件(比如点击操作)
假想有一个很长的计算任务,耗时超过5秒以上,那么在这5秒以内,界面会被阻塞住,用户在界面上的所有的操作都无法响应,如果我们并不是要计算完成才可以响应页面(比如一个超长的文档做高亮),那么我们可以使用宏事件拆分计算任务来做优化。
例如这样子一个超长的计算任务,大概耗时8秒以上
let
如果这些计算并非是响应页面前必须的,那么可以这样子优化:
let
代码把一个连续的计算任务分切成了1000个小任务,并且不会阻塞主线程的工作,完美解决。
总结
很多东西不只是面别人或者被别人面的时候才有用,牛逼的工程师善于解决问题。
onpaste事件不生效_从实际开发中来看JavaScript事件循环的使用场景相关推荐
- iOS开发中didSelectRowAtIndexPath tap事件响应延迟
iOS开发中didSelectRowAtIndexPath tap事件响应延迟 为UITableViewCell添加tapped事件,代码如下: class VideoViewController: ...
- 读《Javascript高级程序设计》中的javascript事件处理程序(事件侦听器)心得
今天读了<Javascript高级程序设计>中的javascript事件处理程序(事件侦听器)部分的内容,总结一些自己的心得: 事件就是用户或者浏览器自身执行的某种动作.例如click . ...
- 好程序员技术文档HTML5开发中的javascript闭包
好程序员技术文档HTML5开发中的javascript闭包,事实上,通过使用闭包,我们可以做很多事情.比如模拟面向对象的代码风格;更优雅,更简洁的表达出代码;在某些方面提升代码的执行效率,同时避免对命 ...
- python编程小知识_分享Python开发中要注意的十个小贴士
大家请注意:这篇文中假设我们都用的是Python 3 1. 列表推导式 你有一个list:bag = [1, 2, 3, 4, 5] 现在你想让所有元素翻倍,让它看起来是这个样子:[2, 4, 6, ...
- 软件开发重要性_在软件开发中考虑时间的重要性
软件开发重要性 by Crunch Tech 通过Crunch Tech 在软件开发中考虑时间的重要性 (The importance of time to think in Software Dev ...
- js初化加载页面时ajax会调用两次的原因_在前端开发中,有哪些因素会导致页面卡顿
前端开发不像后端那样,很少出现有大量算法的场景,但是前端性能也是需要优化的.好的代码是保证网页平稳高性能运行的基础,结合以往开发中遇到的场景,本文对前端网页卡顿的原因进行了梳理和分析,并给出了对应的解 ...
- vue鼠标移动上去提示_关于如何处理vue中鼠标悬停事件的详细说明
最后,在查看结果中,发现滑过鼠标事件将触发该事件,但它将闪烁并清除. 当鼠标停留在单元格上时鼠标滑过事件,遮罩层将消失并重复出现. 开关. 为了缓解这种情况,setTimeout也用于延迟显示和隐藏在 ...
- android监听器在哪里创建,[转载]android开发中创建按钮事件监听器的几种方法
第一种:匿名内部类作为事件监听器类 Button button=(Button) findViewById(R.id.button); button.setOnClickListener(new On ...
- 艾伟_转载:C#中的委托和事件-抛砖引玉
最近在学习委托和事件,在书店里面看了好多书,但是都是迷迷的-- 今天在博客园里面看到了 张子阳 所写的博客C#中的委托和事件:http://www.tracefact.net/CSharp-Progr ...
最新文章
- 为什么输出流会有一个flsh_交流会| “流量”还是“留量”,如何成为电商风口上的赢家?...
- Python常用模块之configparser模块
- apache 限制IP网段访问
- rabbitmq 传递文件_RabbitMQ:计划邮件传递
- 前端学习(3207):js中的事件绑定
- Hibernate 补充 ManyToOne、OneToMany、OneToOne的使用例
- 【PAT - 甲级1005】Spell It Right (20分) (递归输出,水题)
- php hibernate,Hibernate总结
- s400x ugee 驱动_联想_ThinkPad|ThinkCentre|ThinkStation服务与驱动下载_常见问题
- bug10下的工具(以防重新装机)
- dmp标签_一种基于DMP标签的管理平台及方法与流程
- 高速PCB设计入门概念
- 《三峡好人》,《黄金甲》所折射的电影学意义
- 苹果手机微信语音没声音怎么回事_iphonexs没声音,iphonexs扬声器没声怎么回事?...
- openGauss 准备软硬件安装环境
- UNetbootin使用
- 【Hi3519A】测试华为M2221-QL智能摄像头
- 遗传算法优化BP神经网络前后的对比
- 小学计算机课标教学大纲的依据,《中小学课程标准与教学大纲有什么区别和联系》...
- tp6生成带图二维码(大解析)