JavaScript运行模式

  • Post author:
  • Post category:java




单线程

JavaScript是单线程。

JavaScript被定义成单线程,是和它起初功能有关,主要用于操作DOM。比如我们不可能同时删除一个元素,同时给这个元素添加子元素。

所谓单线程,是指JS执行环境中执行代码的线程只有一个。线程下执行代码过程中,会一步一步执行代码,但是如果碰到耗时任务,如果一直等待此行代码执行完毕,肯定会出现“假死”情况。因此,在代码执行过程中,我们能否遇到耗时代码交给相应的API去执行,而不影响我们的主线程?因此在程序运行中,出现了两种模式:同步模式和异步模式。

代码运行的模式是指:运行环境提供的API是以同步或异步模式的方式去工作。



同步模式

在同步模式下,首先当前工作的所有代码会被以匿名函数的方式压入调用栈(程序工作表),在执行时,遇到函数时,会依次将函数压入调用栈,当函数调用完毕,弹出调用栈。直至当前工作的代码执行完毕。

请添加图片描述

同步模式虽然简单,但是如果遇到耗时操作,就会出现页面卡顿,给用户留下特别差的体验。如果仅仅有同步模式,单线程的JS无法同时处理大量的耗时任务。因此异步模式横空出世



异步模式

相比较同步模式,异步模式不会等待这个任务结束才开始下一个任务,对于耗时任务,开启之后立即执行下一个任务,后续逻辑一般会通过回调函数的方式去定义,在内部耗时任务完成后,就会自动执行我们传入的回调函数。

console.log("program begin")

setTimeout(function async1() {
  console.log("我是第一个异步任务-asyncCallback1")
}, 3000)

setTimeout(function async2() {
  console.log("我是第二个异步任务-asyncCallback2")
  setTimeout(function async3() {
      console.log("我是第三个异步任务-asyncCallback3")
  }, 1000)
   console.log("我是第二个异步任务-我还有其他操作")
}, 1000)

console.log("program end")

请添加图片描述

Event Lop 是同时监听调用栈和消息队列。

下图所示是上述程序执行过程中的大概流程,具体流程就不再唠了

在这里插入图片描述

看到这个里有没有大佬会说,JS不是单线程吗?

可以负责任的说,JS确实是单线程。但是浏览器不是单线程,浏览器所提供的的有些API是异步的,这些异步API会有其他线程去执行。执行JS代码的线程永远是单线程。



回调函数

那异步模式是怎样实现的?

回调函数是所有异步方案的根基。

回调函数在我们编程中随处可见,比如我们需要向服务器请求数据,但是我们不知道何时才能拿到数据,去做页面逻辑?那我们(调用者)通过ajax(执行者)去请求数据,然后将拿到数据后的逻辑写到一个函数传递给执行者(ajax),成功拿到数据后,调用此函数,去做页面逻辑。

比如我们使用setimeout模仿ajax请求

function ajax(callback){
  setTimeout(()=>{
    callback();
  }, 1000)
}

ajax(()=>{
  console.log("我已经拿到数据了,我要一系列操作了")
})



参考资料



版权声明:本文为sanfeng_hu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。