• Js的同步异步以及回调函数


    这里是修真院前端小课堂,每篇分享文从

    【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】

    八个方面深度解析前端知识/技能,本篇分享的是:

    【Js的同步异步以及回调函数】

     
    大家好,我是IT修真院深圳分院第06期学员,一枚正直善良的web程序员。
    今天给大家分享一下,修真院官网JS任务中可能会使用到的知识点:
    js同步异步以及回调函数
    1.背景介绍
    什么是同步,什么是异步?

    同步指的是一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。
    异步指的是每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。
    2.知识剖析
    javascript实现异步的原理

    首先js是单线程的语言,即同一时间只能做做一件事。那Js如何实现异步的,异步和单线程不是自相矛盾吗?其实,单线程和异步确实不能同时成为一个语言的特性。js选择了成为单线程的语言,所以它本身不可能是异步的,但js的宿主环境(比如浏览器,Node)是多线程的,宿主环境通过某种方式(事件驱动,下文会讲)使得js具备了异步的属性

    浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程:javascript引擎线程,UI渲染线程,浏览器事件触发线程。

    1.javascript引擎线程是基于事件驱动单线程执行的,JS引擎一直等待着任务队列中任务的到来,然后加以处理,浏览器无论什么时候都只有一个JS线程在运行JS程序。

    2.UI渲染线程负责渲染浏览器界面,当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行。但需要注意UI渲染线程与JS引擎是互斥的,当JS引擎执行时UI线程会被挂起,UI更新会被保存在一个队列中等到JS引擎空闲时立即被执行.

    3.事件触发线程,当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这些事件可来自JavaScript引擎当前执行的代码块如setTimeOut、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等,但由于JS的单线程关系所有这些事件都得排队等待JS引擎处理。

     

    image

    UI线程和JS线程互斥的实例

    <input type="text" value="" name="input" onkeydown="console.log(this.value)">
    <input type="text" value="" name="input" onkeydown="var me=this;setTimeout(function(){console.log(me.value)},0)">
    分析:第一个在keydown的时候,弹出来的是input里原来的value,而第2个在keydown的时候,却能弹出更新后的value,就是因为setTimeout,虽然他的delay设置为0,几乎是即时触发,但还是被添加到了执行队列后面,但就是这个过程,渲染已经完成了,当他回调函数执行时,输出来的已经是更新后的value了。

    注意:js的工作机制是当线程空闲的情况下才会执行异步代码的回调函数

    即当所有同步任务执行完毕后才会执行异步任务的回调函数

    总结:当Js执行到异步任务后,会将异步任务交给浏览器进行执行,当执行有结果时会把异步任务的回调函数插入待处理队列的队尾。

    3.常见问题
    ajax发送异步请求浏览器做了什么
    有哪些常见异步回调函数?
    4.解决方案
    ajax发送异步请求浏览器做了什么?
    Js创建了一个ajax请求
    浏览器另外开启一个ajax引擎线程,执行ajax请求
    执行得到响应后将回调函数放入任务队列中。
    Js执行任务队列中的回调函数。
    有哪些常见的异步回调函数?
    点击事件
    Ajax请求
    定时器
    浏览器处理点击事件的过程
    浏览器开启事件触发线程,等待用户动作,事件触发线程解析为响应事件,转移到javascript引擎线程,排队等候,等待javascript引擎的处理。
    例:
    <!doctype html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    </head>
    <body>
    <div onclick="clickme()">click me</div>
    <script type="text/javascript">
    function clickme() {
    console.log('点击事件')
    }
    for (i=0;i<50000;i++){
    console.log(i)
    }
    </script>
    </body>
    </html>
    在线实例
    这个点击事件会等到for循环执行完毕后才会执行,即我们点击模块它直到for循环执行完毕才会执行

    5.编码实战
    6.扩展思考
    如何实现js的多线程操作?

    Html5的web worker
    7.更多讨论
    Q1:浏览器的UI线程和Js线程为什么是互斥的?

    A1:而因为JS可以操作DOM元素,进而会影响到GUI的渲染结果,因此JS引擎线程与GUI渲染线程是互斥的。
    Q2:异步函数有哪些优点和缺点

    A2:
    优点:
    a)对CPU的使用率高。
    b)不用考虑线程间同步互斥问题。
    缺点:
    a)实现较复杂,要把所有会导致阻塞的操作转化为异步操作。
    b)并发性不好,在有的事件需要长时间占用CPU处理的情况下,其他事件会长时间等待得不到处理。
    c)在多CPU时不如多线程高效。
    Q3:异步函数跟promise之间有什么关系?

    A3:Promise它可以用于异步的回调函数,它跟传统的回调函数相比,promise的异步回调函数代码书写起来更优雅,更便于阅读。
    8.参考文献
    参考一:js的单线程和异步
    参考二:深入理解javascript异步编程障眼法&&h5 web worker实现多线程
    参考三:谈谈JavaScript的异步实现- 小方- 博客园

    PPT
    视频

     

    技能树-IT修真院

    IT修真院是一个免费的线上IT技术学习平台 。

    每个职业以15个左右的task为初学者提供更快速高效的学习方式 ;

    所有task均是从真实项目中提炼出来的技能点,

    强调实战演练+自学优先+师兄辅导的学习方式,

    严格的日报体系,欢乐的交流讨论学习气氛,更有无数师兄师姐帮你解疑!

    点击官网注册 官网,使用师兄邀请链接有优惠。

    更多内容,可以加入IT交流群565734203与大家一起讨论交流

    这里是技能树·IT修真院:https://www.jnshu.com,初学者转行到互联网的聚集地

  • 相关阅读:
    Android:JNI之Java和C层的相互调用及多线程的回调实现
    高通sdm845_la2.0源码编译及使用QFIL刷机
    git常用指令
    Bouml快速使用指南
    Linux内核数据结构之kfifo详解
    输入系统:进程间双向通信(socketpair+binder)
    Android : 跟我学Binder --- (6) JAVA实现
    【LeetCode】167. Two Sum II
    【LeetCode】1. Two Sum
    【LeetCode】206. Reverse Linked List
  • 原文地址:https://www.cnblogs.com/jnshu/p/10153785.html
Copyright © 2020-2023  润新知