Asynchronization and single thread about javascript

需要注意的是,setTimeout()只是将事件插入了"任务队列",必须等到当前代码(执行栈)执行完,主线程才会去执行它指定的回调函数。要是当前代码耗时很长,有可能要等很久,所以并没有办法保证,回调函数一定会在setTimeout()指定的时间执行。 引用原文

setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,意思就是不用再等多少秒了,只要主线程执行栈内的同步任务全部执行完成,栈为空就马上执行。原文2

理解:
js单线程存储两个调用栈:执行栈和事件栈。js在运行的时候永远只有一处代码在执行,但是这段代码来自于执行栈还是事件栈是根据代码内容决定,浏览器中的js引擎中有一个异步进程处理,用来判断js的异步进程是否满足执行条件,如果不满足则不执行,满足就将其放入事件栈中,等待执行栈所有任务执行完成之后在进行调用。

理解引用:三、异步是如何实现的:异步是靠浏览器的两个或者两个以上的常驻线程来完成的,第一个就是js的执行线程,第二个就是事件触发线程,js执行线程发出异步请求给浏览器,浏览器开一个新的请求线程来处理,js执行线程继续执行其他任务。那么事件触发线程呢?他就监听这个请求,如果这个请求完成了,就将该事件插入到JS执行队列的尾部等待JS处理。
链接
黑马课程 p278 279 280
深入理解后的代码:

setTimeout(function(){
    console.log('定时器开始啦')
});

new Promise(function(resolve){
    console.log('马上执行for循环啦');
    for(var i = 0; i < 10000; i++){
        i == 99 && resolve();
    }
}).then(function(){
    console.log('执行then函数啦')
});

console.log('代码执行结束');

输出结果:

马上执行for循环啦
代码执行结束
执行then函数啦
定时器开始啦