一个关于回调的问题
来源:互联网 发布:淘宝加盟诈骗案进展 编辑:程序博客网 时间:2024/06/05 06:35
今天看到一道题蛮有意思的。题目是这样的:
setTimeout(function() { console.log(1)}, 0);new Promise(function executor(resolve) { console.log(2); for( var i=0 ; i<10000 ; i++ ) { i == 9999 && resolve(); } console.log(3);}).then(function() { console.log(4);});console.log(5);
这段代码的输出是什么?
一开始我没细想,以为是2,3,5,1,4
,然后我随手就在chrome的console中运行了一下,发现结果是2,3,5,4,1
。
略微惊讶,,但是随即我想到setTimeout函数好像有个不成文的规定,当time为0时会延迟4ms运行(现在似乎已经写进了标准),这样一想,好像是该是这个结果哦。。
但是我发现了个小问题:
这个console中的结果有个undefined。
一般来讲,这个undefined应该是我这段代码运行完了的返回值啊。。
那么它应该出现在4前面啊!为什么出现在1前面了呢??
带着这个疑问我去搜索了下,发现我不知道的还有蛮多。。。
这个事情要从Event Loop说起。
我们都知道JavaScript是单线程的(虽然web worker能进行多线程的计算),它有个经典的Event Loop事件模型,而实际上就当前的这个程序来说,可以看做有两个任务队列。一个叫macro-task,另一个叫micro-task。根据Promises/A+规范:
- macro-task包括:
script(整体代码)
,setTimeout
,setInterval
,setImmediate
,I/O
,UI rendering
- micro-task包括:
process.nextTick
,Promises(这里指浏览器实现的原生 Promise)
,Object.observe(已废弃)
,MutationObserver
也就是说,浏览器运行这段程序的时候,经历了以下几个步骤:
- 将这段代码放到一个macro-task任务队列中,然后执行
- 执行到setTimeout,将这个setTimeout放到了当前的这个macro-task中,然后继续执行任务
- 执行到了promise,执行promise中的代码,输出2和3,将then回调放入micro-task,然后继续执行
- 输出5,至此执行完了macro-task中的第一个任务,然后执行micro-task中的全部任务,输出了4
- 至此,这段代码执行完毕,输出返回值undefined
- 执行macro-task中的下一个任务,输出1.
所以才看到了那样的结果。
更多内容请参考:知乎问题
0 0
- 一个关于回调的问题
- 一个关于Webservices的问题
- 关于类的一个问题
- 关于MVC的一个问题
- 一个关于ASP的问题..
- 一个关于多态性的问题
- 关于.Text的一个问题
- 关于javamail的一个问题
- 关于ActiveXObject的一个问题
- 一个关于#include的问题
- 关于C的 一个问题
- 一个关于#include的问题
- 关于.Text的一个问题
- 一个关于#include的问题
- 一个关于#include的问题
- 一个关于#include的问题
- 一个关于JavaScript的问题
- 关于join的一个问题
- 使用Maven构建Java项目
- JavaScript函数赋值给变量
- Test
- 106. Construct Binary Tree from Inorder and Postorder Traversal
- [Kafka]_0
- 一个关于回调的问题
- Cocos在android studio下的开发
- 传统MVP用在项目中是真的方便还是累赘?
- 动态规划Dynamic Programming的总结
- TCP/IP协议 之IPV4与IPV6的区别
- 建造者模式
- Android 利用Sensor现实了传感器
- java 多线程 线程之间的通信
- 设计模式(6)-原型模式