Promise与setTimeout

Promise是ES6新提出的概念,可以把它看作是异步操作和回调函数的中转站,或者是保存异步操作结果的容器。通过Promise,可以将异步操作通过同步流程表现出来。具体介绍参考ESMAScript6 入门。

之前在网上看到一道题目:

(function test() {
setTimeout(function() {console.log(4)}, 0);
new Promise(function executor(resolve) {
console.log(1);
for( var i=0 ; i<10000 ; i++ ) {
i == 9999 && resolve();
}
console.log(2);
}).then(function() {
console.log(5);
});
console.log(3);
})()

输出结果为 1 2 3 5 4 

这道题目涉及到JavaScript 的事件循环机制。

JavaScript有一个调用栈。在执行代码时,遇到同步任务就放入调用栈中执行,遇到异步任务,如 Ajax   setTimeout 等,就将其放入浏览器的其他模块中去处理。处理完成后将回调函数放入任务队列中,等待调用栈中的任务执行完成后就开始执行。下面以setTimeout为例。

setTimeout(function(){console.log('123')},1000)

浏览器将其放入调用栈后,检测到是异步任务,将其放入其他模块中进行处理,此时计时器开始计时,1000毫秒后将回调函数放入任务队列中,等待调用栈执行完毕后开始执行。

关于事件循环机制详见 深入浅出Javascript事件循环机制(上) - 知乎专栏


当setTimeout和Promise放在一起的时候,由于Promise的任务队列的优先级更高,所以在处理宛调用栈中的任务后,会先处理Promise所在的任务队列。所以输出结果为 1 2 3 5 4 而不是  1 2 3 4 5

关于这道题更详细的解释可以参考从Promise来看JavaScript中的Event Loop、Tasks和Microtasks

你可能感兴趣的:(JavaScript)