Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【Javascript】探究javascript中的堆/栈/任务队列与并发模型 event loop的关系 #12

Open
AwesomeDevin opened this issue May 14, 2019 · 0 comments

Comments

@AwesomeDevin
Copy link
Owner

AwesomeDevin commented May 14, 2019

堆/栈/队列

在javascript中,存在调用栈 (call stack)内存堆(memory heap) ,程序中函数依次进入栈中等待执行,若执行时遇到异步方法,该异步方法会被添加到用于回调的任务队列(task queue)中,【即JavaScript执行引擎的单线程拥有一个调用栈、内存堆和一个任务队列】

调用栈 (call stack):CallStack是用来处理函数调用与返回的。特点是先进后出,每次调用一个函数,Javascript运行时会生成一个新的调用结构压入CallStack。而函数调用结束返回时,JavaScript运行时会将栈顶的调用结构弹出。由于栈的LIFO特性,每次弹出的必然是最新调用的那个函数的结构。函数调用会形成了一个堆栈帧,存放基本数据类型的变量

内存堆(memory head):引用数据类型被存放在堆中,在我们进行浅复制时,我们改变的只是引用数据类型在栈内存中的引用地址,实际上它在堆内存中的引用地址仍然没有发生变化

任务队列(task queue):javaScript 运行时包含了一个待处理的任务队列。

并发模型 与 EventLoop

javascript引擎是单线程的,它的并发模型基于Event Loop(事件循环)

当线程中的同步任务执行完,执行栈为空时,则从任务队列(task queue)中取出异步任务进行处理。这个处理过程包含了调用与这个任务相关联的函数(以及因而创建了一个初始堆栈帧)。当执行栈再次为空的时候,也就意味着该任务处理结束,从任务队列中取出下一个异步任务进行处理,不断重复,这个过程是循环不断的, 所以整个的这种运行机制又称为Event Loop(事件循环).

Task Queue 任务队列

任务队列有宏任务队列微任务队列,

  • 宏任务:script(全局任务), setTimeout, setInterval, setImmediate, I/O, UI rendering.
  • 微任务:process.nextTick, Promise, Object.observer, MutationObserver.
每次事件循环的时候:
  • 微任务/宏任务在相同作用域下,会先执行微任务,再执行宏任务
      setTimeout(()=>{
        console.log('timer')
      })
      Promise.resolve('promise').then((res)=>{
        console.log(res)
      })

  • 宏任务处于微任务作用域下,会先执行微任务,再执行微任务中的宏任务
      Promise.resolve('promise').then((res)=>{
        console.log(res)
        setTimeout(()=>{
          console.log('timer')
        })
      })

  • 微任务处于宏任务作用域下时,会先执行宏任务队列中的任务,然后再执行微任务队列中的任 务,在当前的微任务队列没有执行完成时,是不会执行下一个宏任务的。
        Promise.resolve('promise1').then((res)=>{
          console.log(res)
          Promise.resolve('promise2').then((res)=>{
            console.log(res)
            Promise.resolve('promise3').then((res)=>{
              console.log(res)
            })
          })
          setTimeout(()=>{
            console.log('timer')
          })
        })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant