js的异步事件循环机制,js异步任务执行顺序

  js的异步事件循环机制,js异步任务执行顺序

  本文给大家带来一些javascript的知识,主要介绍JavaScript事件周期的同步任务和异步任务。文章围绕主题,详细介绍了内容,具有一定的参考价值。有需要的朋友可以参考一下。

  【相关推荐:javascript视频教程,web前端】

  

前言

  首先,在学习js中的同步和异步之前,我们需要了解js是单线程的。为什么一定要单线程?要看它的使用场景。它主要用于让用户与页面进行交互。所以假设js是多线程的。在这个线程中,用户单击一个按钮来添加一个DOM节点,在另一个线程中,用户单击这个按钮来删除另一个DOM节点。然后js就不知道听谁的了。同步和异步出现的原因是什么?假设没有异步,当我们向服务器请求数据时,可能会因为网络不好而卡半天。此时,由于是同步的,网页必须等待数据请求返回,才能继续与用户交互。这样会导致整个网页莫名其妙的卡顿,用户体验非常不好。

  

执行栈与任务队列

  

执行栈

  先不说执行栈是什么,先说栈是什么。栈就像一个桶。先放进去的一定是最后拿出来的,也就是人们常说的先进后出。

   那么执行栈就是把图中的内容块变成代码任务,光说肯定说不明白,还是得上代码:

  函数fn(计数){

  if (count=0)返回

  fn(计数- 1)

  console.log(计数)

  }

  这是一个非常简单的递归代码。这里我们直接上图解释一下(其实这里的绘制并不严谨,栈底应该是全局执行上下文):

  js中的所有任务都会在主线程上执行,然后形成一个执行栈(请记住这个!)

  

任务队列

  那么队列和栈是相反的,队列是FIFO。其实很好理解。跟平时排队是一个道理。先入队者必先出。那么任务队列通俗的理解就是用来放置异步任务的回调函数(这个也请记住!)

  

同步任务与异步任务

  先上一点概念性的东西,打个基础:

  

同步任务

  很多人在理解同步任务的语义时,都被它弄糊涂了。事实上,同步任务并不是同时执行的。它必须等待上一个执行任务完成,然后才能执行下一个任务。这里并不晦涩,而是写一个简单的代码来解释它:

  console.log(1)

  console.log(2)

  Console.log(3)代码很简单吧?很明显,输出结果是1,2,3,这是同步码,我们可以总结一下。同步任务是在主线程上面排队,然后逐个进入执行栈进行执行,直到执行栈为空。

  

异步任务

  还是直接举个栗子:

  console.log(1)

  setTimeout(()={

  console.log(2)

  }, 1000)

  Console.log(3)这段代码的输出与上面的同步代码不同。它的输出序列是1,3,2,是异步代码。它将不会在执行序列中执行。

  同样我们用官方话语总结一下:异步任务是指不进入主线程而进入‘事件队列’的任务。只有当‘任务队列’通知主线程可以执行异步任务时,任务才会进入主线程执行。不懂也没关系。后面说到事件循环,就发人深省了。

  

js的执行机制

  先上比较晦涩难懂的概念:

  1.同步任务由JavaScript主线程依次执行。2.异步任务委托给主机环境。3.异步任务完成后,相应的回调函数将被添加到任务队列中执行。任务队列分为宏任务队列和微任务队列,微任务队列优先。常见的微任务是new Promise()then .常见的宏任务是timer4.。JavaScript主线程的执行栈清空后,任务队列中的回调函数将被依次读取并执行。5.JavaScript主线程不断重复上述步骤4,在执行回调函数时会遵循上述四个步骤。Js总是从任务队列中取出回调函数,然后放在主线程中执行。这是一个循环的过程,所以叫事件循环。

  这个还是要简单粗暴的来段代码会更直观一点:

  const Promise=new Promise((resolve,reject)={

  console . log(1);

  setTimeout(()={

  console . log( timer start );

  解决(“成功”);

  console . log(“timerEnd”);

  }, 0);

  console . log(2);

  });

  promise.then((res)={

  console . log(RES);

  });

  console . log(4);现在我们按照上面的规则一步一步来分析这段代码。不知道承诺也没关系。我保证不会影响你对事件循环的理解。现在就把自己当成js代码的检察官,把它们放到正确的“位置”

  检察官的第一步是判断哪些是同步码,哪些是异步码,OK。首先,从上到下,Promise本身是同步的,所以它应该在主线程上排队,然后继续看,pomise.then是异步任务,属于微任务。它的回调函数应该在微任务的队列中(还没有),最后输出的语句是同步代码,应该在主线程上排队。第二步是在主线程上执行同步代码。首先,有一个承诺队列,所以我先输出1,然后有一个定时器,所以我应该暂停它执行。由于没有时间延迟,回调函数直接放入宏任务队列,继续执行代码。遇到打印,直接输出2。现在主线程还有其他同步代码吗?是不是还有一个output语句,所以4就是output?现在,主线程上的同步代码已经执行完毕。步骤3读取任务队列。因为微任务队列上什么都没有(Promise的状态没有改变,promise.then()不会被执行),所以读取宏任务队列上的回调函数。回调函数进入主线程执行。首先输出timerStart,然后承诺状态变化,然后遇到另一个output语句,输出timerEnd。既然主线程上什么都没有,我们必须看看任务队列上是否有什么。第四步:因为承诺状态发生了变化,所以微任务队列上有一个回调函数。执行output语句,res为成功,输出成功【相关推荐:javascript视频教程,web前端】。以上是JavaScript事件循环的同步任务和异步任务的细节。更多请关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: