你应该看看
所有被调用的js函数都会被放入栈,按照后入先出的顺序依次执行。理解这个对于理解js异步函数非常重要。JavaScript(引擎)是单线程的,Event loop并不属于JavaScript本身,但JavaScript的运行环境是多线程/多进程的,运行环境实现了Event loop。,js的单线程执行完美避开了GUI(css图形界面渲染)冲突,但同时js的运行环境又是多线程的,常见的线程有js主线程,GUI图形界面绘制进程,点击事件等进程,setTimeout/setInterVal时间进程,这么多进程共同协作,才构成了js灵活多变的浏览器操作。这样的设计异常巧妙。而html5又加入了web worker,但它是另一个进程,和我们所讨论的互不干涉,es6又加入了promise.then,但是promise真的不属于多线程,promise内部原理我是理解不了。 但是请看下图,
我们的JavaScript的执行过程是单线程的,所有的任务可以看做存放在两个队列中——执行队列和事件队列。
执行队列里面是所有同步代码的任务,事件队列里面是所有异步代码的宏任务,而我们的微任务,是处在两个队列之间。
当JavaScript执行时,优先执行完所有同步代码,遇到对应的异步代码,就会根据其任务类型存到对应队列(宏任务放入事件队列,微任务放入执行队列之后,事件队列之前);当执行完同步代码之后,就会执行位于执行队列和事件队列之间的微任务,然后再执行事件队列中的宏任务。
😴醉了,根本不是线程的问题,promise内部是保证一定完成,才进行下一步,所以必须先将promise内部函数执行完毕,才进行then后的函数,而then则属于微任务,所以它不是setTimeout和setImmediate这种宏任务的的对手,setTimeout线程位于setImmediate线程后面,所以then里面setImmediate先执行,setTimeout后执行
我将promise命名一个字面量,输出的结果却又不一样了。真令人困惑。promise被分叉成两个.then 同样的函数我执行5次,如下图,居然发现输出结果不一致,为什么呢??? 发现规律就是1永远排在最前面,246为一组,35为一组,这两组不定期排序。。本身是不是说明了事情就是promise的这两个单独的then让promise分叉了,任意时间返回结果。。。但是35是setTimeout线程,而246则是setImmediate线程,settimeout线程不是永远应该排在setImmediate后面么。。。
如图,请认真查看这个报错的stack trace栈追踪,事件执行顺序依然是 foo -> bar -> baz -> object,而这条追踪对应的是error发生的时候记录的栈追踪,非常有意思。 当我用node去调用他的时候,没有发生任何变化。 浏览器的报错栈树,最外层的anonymous则是最外层我们调用js本身的main.js,这属于浏览器的栈追踪。
老司机应该经常看到这种报错,超过最大限量的栈调用