chaihongjun.me

javascript事件调用机制

虽然javascript是单线程的,但是可以创建多个子线程去执行一些操作(DOM操作除外),javascript的事件循环机制来调度事件执行。

function a1()
  {console.log('a1')
  setTimeout(function(){console.log('a2')},6000)}
  
function b1(){
  console.log('b1')
  setTimeout(function(){console.log('b2')},3000)}
  
function c1(){console.log('c1')}

a1()
b1()
c1()

上面的代码使用setTimeout模拟异步操作(因为有延时)


整个代码执行流程:

首先是将代码全部加载进内存并“逐行扫描”,发现前面3个都是函数声明,直到出现a1函数的调用。

读到a1()方法:

console.log('a1'):同步任务=> 输出a1

setTimeout(function(){console.log('a2')},6000):异步任务,不立即执行,丢到宏任务队列等待,这个任务队列专门是用来给异步任务排队的

开始读b1()方法(和a1()同理):

console.log('b1'):同步任务=> 输出b1

setTimeout(function(){console.log('b2')},3000):异步任务,不立即执行,丢到宏任务队列等待,这个时候任务队列里面已经有两个异步在等待执行了。

开始读c1()方法:

console.log('c1'):同步任务=> 输出c1

以上三个同步任务执行完毕,而且整个当前上下文环境(当前是全局作用域环境)的同步任务都执行完毕了,接着,会进入任务队列调取异步任务,将异步任务放入执行栈进行任务执行。

这时需要注意的是,两个异步任务(setTimeout)都有一个等待一定时间之后再执行的设定,第一个等待3秒,第二个等待6秒。也就是说,当前上下文环境下,全部同步任务完成之后,前往任务队列(这里等待的都是异步任务),发现第一个异步任务,我们称作A,要等6秒之后再拿到执行栈去执行,第二个异步,我们称作B,要等3秒之后拿去执行。虽然A在任务队列里排队在B的前面,但是B要先于A被拿到调用栈,所以执行顺序就变成了:先console.log('b2')再console.log('a2').最终的输出顺序是

a1 b1 c1 b2 a2


知识共享许可协议本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。作者:chaihongjun»

相关推荐