JS中单线程和事件循环详解

Js 是单线程,js代码从上到下依次执行,比如我们写了两个函数,肯定是上面的函数先执行,下面的函数后执行。但是这种单线程有一个非常大的问题,那就是遇到耗时的任务,后面的任务只能等待它执行完,才能进行。比如ajax 请求,它从服务器上获取数据,这本来就耗时间, 如果网络再慢,就更耗时间,那么我们只能等待返回结果,结果出来之后再向下执行,等待的过程中,用户什么都不能做,如果是在渲染阶段,也会阻止渲染UI, 用户只能看到空白页面,体验太差。

对于这种比较耗时间的任务怎么办,js 决定把它放到一边,先运行后面的任务,然后再回来处理这些耗时的任务。这就引入了异步的概念,因为我们书写代码的顺序和它执行顺序是不一致了。下面有三个函数,两个基本函数,和一个ajax 函数(作异步操作),我们的书写顺序是ajax -> add -> subtract, 但执行顺序却是 add -> sbutract -> ajax;

function add(num1,num2) {    return num1 + num2;}function subtract(num1,num2) {    return num2 - num1}function ajax() {    var url = 'http://jsonplaceholder.typicode.com/posts/1';    var xhr = new XMLHttpRequest();    xhr.open("GET",url);     xhr.onload= function () {        console.log(xhr.responseText)    }    xhr.send()}ajax();

登录后复制

console.log(add(3,5))

登录后复制

console.log(subtract(3,5))

登录后复制

  这又引出了另 一个问题,异步的任务放到什么地方了?它以后回来执行,那什么时候执行?这里其实要注意一个问题,真正执行ajax操作的不是我们的js,而是浏览器,是我们的浏览器发出的http 请求。当js 执行到ajax 函数的时候,它其实是告诉浏览器去执行http 请求,然后就立即返回,执行它后面的代码,就是add 和substract  函数。那么浏览器执行完http请求,从服务器拿到了数据,怎么办?它这时执行我们的回调函数(onload 函数),就是把返回的数据传递给回调函数,然后把回调函数插入到事件(任务)队列中。js运行完add 和subtract 函数时,就没有事情可以做了,它就会去轮询事件(任务)队列,刚一轮询,它就发现,有一个onload 回调函数,那么它就会把它取出来执行这个函数。在程序运行过程中,js会一直执行轮询,直到程序结束。

  Js 代码在整个程序的运行过程中分为两个部分,一种是像add 函数这种,另一种是像ajax onload 回调函数这种,相对应js 运行也分成了两个部分,一个是主线程,一个是任务(异步回调函数)队列。

  js代码具体运行如下:

  1, js 代码一加载进来,它就会从上到下依次执行,它也就进入一个全局执行环境,当它遇到ajax 异步操作的时候,它会告诉浏览器去执行请求,然后立即返回,执行下面的代码,遇到add函数调用,它就会进入函数执行环境,执行完add函数时,它又遇到subtract 函数,它又会进入函数执行环境。当然这里比较简单,没有嵌套函数。如果函数中还嵌套一个函数,那么它就会进入子函数的执行环境,像下图一样,这就形成了一个执行栈,上面的执行后,再执行下面的,直到全局执行环境中的代码执行完毕,执行栈为空, 这就是就是js 的主线程。

JS中单线程和事件循环详解

  2,浏览器去执行http 请求, 在未来的一段时间内,它或者从服务器获得数据或者失败,这时它就会把我们注册的成功或失败的回调函数放入到任务(回调函数)队例中。

JS中单线程和事件循环详解

  3, 当执行栈中的所有代码执行完毕后,就是执行栈为空时,js就会去轮询我们的任务队列(左边图片),如果有任务,它就会从任务队列的起始位置 取出第一个任务(注册的回调函数)放到执行栈去执行(右边图片),等这个回调函数执行完毕后,执行栈再为空,js再去轮询我们的任务队列,如果还有回调函数,它再取出第一个放到执行栈执行。在整个程序的执行过程中,js 会一直轮询我们的任务队列,一有任务,就会执行,这就是事件循环

JS中单线程和事件循环详解JS中单线程和事件循环详解

  所有的程序都是栈中执行,只有执行栈空了,它有能力处理下一个任务。只要一个函数进入到执行栈,栈就不为空,栈不为空,就不能处理下一个函数,只能等到函数执行完毕。这就是所谓的 “run–to-complete ” 一次只能做一件事情。这也要求我们的回调函数中,不能执行太多任务,如果执行太多任务,栈就不为空,也就阻止了下一个任务的执行,造成阻塞。

 以上所述,就是js 中的非阻塞。

相关推荐:

JavaScript运行机制之为什么JavaScript是单线程

单线程JS与多线程浏览器的使用

原生JS异步和单线程详解

以上就是JS中单线程和事件循环详解的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2776643.html

(0)
上一篇 2025年3月8日 14:54:36
下一篇 2025年3月8日 14:54:43

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • javascript日期操作详解(整理)_时间日期

    本篇文章给大家分享的是javascript日期操作详解,内容挺不错的,希望可以帮助到有需要的朋友 时间对象是一个我们经常要用到的对象,无论是做时间输出、时间判断等操作时都与这个对象离不开。除开JavaScript中的时间对象外,在VbScr…

    编程技术 2025年3月8日
    200
  • js中delete操作符与内部属性实例详解

    本文主要和大家分享js中delete操作符与内部属性实例详解,在讲解Configurable之前,我们首先来看一道面试题: a = 1;console.log( window.a ); // 1console.log( delete win…

    编程技术 2025年3月8日
    200
  • 如何理解js中的闭包

    闭包(closure)是javascript的一大难点,也是它的特色。很多高级应用都要依靠闭包来实现。本次的这篇文章主要是和大家分享了如何理解js中的闭包 ,有需要的小伙伴可以看一下 1、变量作用域 要理解闭包,首先要理解javascrip…

    编程技术 2025年3月8日
    200
  • Angular开发实践之服务端渲染_AngularJS

    这篇文章主要介绍了angular开发实践之服务端渲染,内容还是挺不错的,现在分享给大家,也给大家做个参考。一起过来看看吧 Angular Universal Angular在服务端渲染方面提供一套前后端同构解决方案,它就是Angular U…

    2025年3月8日 编程技术
    200
  • Vue中computed与methods的区别详解_vue.js

    这篇文章主要介绍了vue中computed与methods的区别详解,内容还是觉得挺不错的,现在分享给大家,也给大家做个参考。一起过来看看吧 Vue中computed可以用来简单的拼接需要展示的数据 computed and methods…

    2025年3月8日
    200
  • 使用Vue构建可重用的分页组件

    分页组件在web项目中是十分常见的组件,让我们使用vue构建可重用的分页组件,关于基本结构和相关事件监听大家参考下本文 Web应用程序中资源分页不仅对性能很有帮助,而且从用户体验的角度来说也是非常有用的。在这篇文章中,将了解如何使用Vue创…

    2025年3月8日 编程技术
    200
  • 五种JavaScript常见函数总结

    在 JavaScript 中有一些问题会被拿出来经常讨论,这些问题每个人都有不同的思路,想要理解这些问题,最好的方法就是自己实现一遍,话不多说,开始正题。本篇文章给大家分享的是 五种JavaScript常见函数总结,内容挺不错的,希望可以帮…

    编程技术 2025年3月8日
    200
  • ajax分页查询图文详解

    这次给大家带来ajax分页查询图文详解,ajax分页查询的注意事项有哪些,下面就是实战案例,一起来看一下。 (1)先写个显示数据的页面,分页查询需要那几个部分呢? 1.首先是查询的文本框输入,还有查询按钮,那么就开始写代码吧 //输入查询字…

    2025年3月8日 编程技术
    200
  • ajax三级联动图文详解(附代码)

    这次给大家带来ajax三级联动图文详解(附代码),ajax实现三级联动的注意事项有哪些,下面就是实战案例,一起来看一下。 ajax 实现三级联动,相当于写了一个小插件,用的时候直接拿过来用就可以了,这里我用了数据库中的chinastates…

    2025年3月8日
    200
  • js自执行函数

    这次的这篇文章向大家分享的内容是js自执行函数 ,有需要的朋友可以参考一下 1 用自执行函数来包装代码格式 APP = function(){     var a,b; //变量a、b外部不可见     return {          …

    编程技术 2025年3月8日
    200

发表回复

登录后才能评论