javascript中异步promise等的执行顺序问题

下面的一段JS代码

<script>
    setTimeout(function(){
        console.log("1")
    });
    new Promise(function(resolve){
        console.log("2")
        resolve();
    }).then(function(){
        console.log("3")
    })
    console.log("4")
</script>

上面的的运行结果是
2
4
3
1
百思不得其解,为什么是2先出,setTimeout后面没有秒数不是应该直接执行吗?,而且3不是应该在2后面输出吗?为什么到4后面了?

阅读 4.4k
7 个回答

setTimeout 默认值是0,所以2先出
然后不管同步还是异步,在浏览器端,Promise会使用MutationObserver监听一个document.createTextNode(''),然后通过改变node.data的值来触发observer,执行callback,而在事件循环中,MutationObserver属于微任务,会比setTimeout 先运行

es6-promise asap.js

const BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;

function useMutationObserver() {
  let iterations = 0;
  const observer = new BrowserMutationObserver(flush);
  const node = document.createTextNode('');
  observer.observe(node, { characterData: true });

  return () => {
    node.data = (iterations = ++iterations % 2);
  };
}

if (isNode) {
  scheduleFlush = useNextTick();
} else if (BrowserMutationObserver) {
  scheduleFlush = useMutationObserver();
} else if (isWorker) {
  scheduleFlush = useMessageChannel();
} else if (browserWindow === undefined && typeof require === 'function') {
  scheduleFlush = attemptVertx();
} else {
  scheduleFlush = useSetTimeout();
}

setTimeout是宏任务,promise是微任务,执行顺序是先同步,再微任务,再宏任务,new Promise是立即执行,所以是2431,建议你看一下宏任务和微任务的相关文章

首先遇到setTimeout,异步,代码第一次轮询并不会直接执行,而是在下一次轮询时执行,其次,setTimeout不写时间默认是0,但是浏览器厂商约定的最小时间是4,这个无疑 演示器是最后输出的;之后的几行代码都是同步执行了

Promise里面的代码是顺序执行,then回调才会放在微任务中

默认 setTimeout在其他代码运行后执行

setTimeout会产生宏任务,promise的回调则是微任务,同一次时间循环中,微任务会现在宏任务前面执行,所以是3,1;其他的则是同步代码,是2,4,组合就是2,4,3,1.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题