任务队列、回调队列、事件循环( Event Loop ):
任务队列( Task Queue ):主线程执行完毕后所触发的异步任务( WebAPIs ),叫任务队列;
回调队列( Callback Queue ):这些异步 WebAPI 执行完成后得到的结果,会添加到 callback queue 中;
事件循环( Event Loop ):只要主线程的同步任务执行完毕,就会不断的读取 “回调队列” 中的回调函数,到主线程中执行,这个过程不断循环往复;
只要主线程空了,就会去读取”任务队列”,这就是JavaScript的运行机制。这个过程会不断的重复。
如何知道主线程执行执行完毕?JS引擎存在 monitoring process 进程,会持续不断的检查主线程执行为空,一旦为空,就会去 callback queue 中检查是否有等待被调用的函数。
console.log(‘1’);
setTimeout(function() {
console.log(‘2’);
}, 0);
console.log(‘3’); // 1 走主线程 3 回调队列 2 回调队列
打印1
遇到 WebAPI( setTimeout ) ,浏览器新开定时器线程处理,执行完成后把回调函数存放到回调队列中。专业一点的说法: JS 引擎遇到异步任务后不会一直等待其返回结果,而是将这个任务挂起交給其他浏览器线程处理,自己继续执行主线程中的其他任务。这个异步任务执行完毕后,把结果返回给回调队列。被放入的代码不会被立即执行。而是当主线程所有同步任务执行完毕, monitoring process(监控流程) 进程就会把 “回调队列” 中的第一个回调代码放入主线程。然后主线程执行代码。如此反复,打印3 异步 setTimeout 不会阻塞同步代码,因此会首先打印3;
主线程执行完毕后,执行 Callback Queue 打印2;
基于前面的介绍,JS 引擎在执行这段代码时,首先把第一行和第三行代码存入执行栈,把第二行代码存入 “任务队列”,只有当执行栈清空以后,主线程才会读取 “任务队列”,这里的 0毫秒实际上表示的意思是:执行栈清空以后,主线程立即读取存放在 “任务队列” 中的该段代码,所以输入的结果是 1 3 2
WebAPI概念 :( setTimeout,DOM事件,ajax事件 )
原创文章,作者:端木书台,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/277203.html