JavaScript 既然是单线程语言,为什么 setTimeout 不会阻塞线程?
先看下面的代码 function printHello() { console.log("Hello"); } function printWorld() { console.log("World"); } printHello(); // 输出 Hello printWorld(); // 输出 World 在 JavaScript 中,存在一个全局调用栈(Global Call Stack)。当我们调用 printHello 时,会将该方法加入到栈中,由于 JavaScript 是单线程执行机制(同一时间只执行一个命令),所以会在执行完成了 printHello 之后再执行 printWorld。 那么现在就引入标题中的问题,JavaScript 既然是单线程语言,为什么 setTimeout 不会阻塞线程? function printHello() { console.log("Hello"); } function printWorld() { console.log("World"); } setTimeout(printHello, 1000); printWorld(); 表面上来看 setTimeout 也是一个方法,他的定义可能是这样: function setTimeout(callbackFunc, interval) { // .... } 那么按照 JS 单线程理论来说,应该是先将 setTimeout 方法压入全局调用栈,并且执行该方法,等待 1 秒钟,然后再执行 printWorld 才对。但实际上我们都知道,打印的结果会是 “World” 然后 “Hello”,这是为什么? Web Browser API & Callback Queue 事实上 setTimeout 并不是完全是 JS 代码,而是属于 Web Browser API 中的方法。就像名字中所指的那样, JS 调用了 setTimeout 之后,浏览器(Web Browser)会去创建一个 timer,同时将我们传入 setTimeout 的方法 - printHello 加入到 Callback Queue(回调队列) 中。 ...