javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JS事件循环

JavaScript事件循环同步任务与异步任务

作者:​ RachelLenyan​

这篇文章主要介绍了JavaScript事件循环同步任务与异步任务,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下

前言

首先,在学习js中同步异步的问题前,需要明白,js是单线程的,为什么它得是单线程的呢?这得从它的使用场景来看了,它主要是用来让用户与页面进行交互的吧。那么假设js是多线程的,在这个线程里面,用户点击某个按钮会增加一个DOM节点,在另一个线程里面,用户点击这个按钮又会删除一个DOM节点,那么此时js就不知道该听谁的了。那同步异步的出现又是为了什么呢?假设没有异步,那么我们在向服务器请求数据时,可能会因为网络不好,卡了半天,这时候因为是同步的,所以网页必须等待数据请求回来才能继续和用户交互,这样会导致整个网页很奇怪的卡住了,用户体验很不好。

执行栈与任务队列

执行栈

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

function fn (count) {
            if (count <= 0) return
            fn(count - 1)
            console.log(count)
        }
fn(3)

这是一段很简单的递归代码,这里我们直接上图解释(这里其实画的不严谨,栈底应该是全局执行上下文):

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

任务队列

那么队列和栈则是相反的,队列是先进先出的。其实很好理解,和我们平时排队是一个道理,先进入队伍的人肯定先出来。那么任务队列通俗理解就是用来放置异步任务的回调函数的(也请记住这一点!!!)

同步任务与异步任务

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

同步任务

很多人在理解同步任务的时候会被它的语义搞混,其实同步任务不是同步一起执行的。它是要等待上一个执行任务结束才可以执行下一个任务,这里说起来也并不晦涩难懂,但是还是写段简单的代码解释一下:

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,这就是异步代码,它并不会按照执行顺序去执行,

同样我们用官方话语总结一下:异步任务指的是,不进入主线程、而进入"任务队列"(Event queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行 如果不理解没有关系,后面说到了事件循环就会醍醐灌顶了。

js的执行机制

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

js一直从任务队列中取回调函数,然后放入主线程中执行,这是一个循环不断的过程,所以把它叫做事件循环。

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

const promise = new Promise((resolve, reject) => {
      console.log(1);
      setTimeout(() => {
          console.log("timerStart");
          resolve("success");
          console.log("timerEnd");
       }, 0);
      console.log(2);
  });
  promise.then((res) => {
      console.log(res);
  });
  console.log(4);

现在我们根据上面的规则一步一步分析这段代码,如果不懂Promise也没有关系,我保证这并不影响你对事件循环的理解。现在你就把自己当成js代码的检察官,要正确把它们放在合适的“位置”

结语

到此这篇关于JavaScript事件循环同步任务与异步任务的文章就介绍到这了,更多相关JS事件循环 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文