zoukankan      html  css  js  c++  java
  • js 事件循环机制 EventLoop

    js 的非阻塞I/O  就是由事件循环机制实现的

    众所周知  js是单线程的 也就是上一个任务完成后才能开始新的任务 

    那js碰到ajxa和定时器、promise这些异步任务怎么办那?这时候就出现了事件队列。

    js的主要执行栈 称为主栈

    用ajax举例:

      代码执行的时候如果遇到ajax怎么办,ajax事件的实现 是浏览器上的一个功能或者说是线程,当js主栈执行到ajax事件,js会告诉浏览器让浏览器去请求,然后js主栈不会去等ajax是否请求成功,js主栈继续执行,等所有js的同步任务执行完之后,js主栈就会读取这个“事件队列”了,把事件队列里面的第一个事件,压入主栈执行,那么事件队列的里的事件是怎么来的那?(主线程从"事件队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环))

      刚才说过js的主栈执行到ajax事件,js会告诉浏览器让浏览器去请求,然后浏览器请求并且返回结果,那么那他会把,ajax的回调函数放到事件队列的尾部,ajax完成时间是不定的,如果网络延迟它可能很慢才有结果,这个时候 js的主栈把所有任务都执行完毕了,而且因为ajax没有返回结果,那么js主栈的主栈会循环不断的查看事件队列里面有没有可执行的事件(回调函数),也就是说ajax什么时候返回,js主栈什么时候执行ajax的回调函数。(其他的异步任务也是一样的,promise是直接把当前的回调函数放到事件队列里面)

      上面说的事件循环机制,就形成为了非阻塞I/O。

      下面举个例子来测试一下吧:

       这里说明下,setTimeout()也是浏览器上的,他没有设置时间,但是setTimeout()最快执行速度3毫秒(注意这里说的是最快执行速度)说明他的时间是不准确的。

      Promise是立刻向事件队列里面添加一个回调函数,所以比setTImeout快。这也就能解释他的执行顺序了。

      刚才我说setTimeout 执行时间是不准确的,如果设置setTimeout 执行时间是5毫秒,是因为他最后执行完是向事件队列里面添加的,如果我的主栈的的代码计算量庞大,是10毫秒,那么你们想想,执行setTimeout回调的时间不就是10毫秒了吗?

  • 相关阅读:
    aspnetcore identity result.Succeeded SignInManager.IsSignedIn(User) false?
    RFID
    window 关机
    有赞零售小票打印图片二值化方案
    条码打印
    音频基本概念
    2008R2 部署 aspnetcore repair failed 函数不正确
    IIS 字符串过长
    解决MVC Json序列化的循环引用问题/EF Json序列化循引用问题---Newtonsoft.Json
    book
  • 原文地址:https://www.cnblogs.com/sxldy/p/10980811.html
Copyright © 2011-2022 走看看