zoukankan      html  css  js  c++  java
  • setTimeout、Promise、Async/Await 的执行顺序

    问题描述:以下这段代码的执行结果
      async function async1() {
            console.log('async1 start');
            await async2();
            console.log('asnyc1 end');
        }
        async function async2() {
            console.log('async2');
        }
        console.log('script start');
        setTimeout(() => {
            console.log('setTimeOut');
        }, 0);
        async1();
        new Promise(function (reslove) {
            console.log('promise1');
            reslove();
        }).then(function () {
            console.log('promise2');
        })
        console.log('script end');
    解决问题:
    要了解代码的执行顺序 必须先了解 JS的运行机制
    •  Javascript 有一个 main thread 主线程和 call-stack 调用栈(执行栈),所有的任务都会被放到调用栈等待主线程执行。
    •    JS调用栈采用的是后进先出的规则,当函数执行的时候,会被添加到栈的顶部,当执行栈执行完成后,就会从栈顶移出,直到栈内被清空。
    •  Javascript单线程任务被分为同步任务异步任务,同步任务会在调用栈中按照顺序等待主线程依次执行,异步任务会在异步任务有了结果后,将注册的回调函数放入任务队列中等待主线程空闲的时候(调用栈被清空),被读取到栈内等待主线程的执行。

     

    JavaScript中,任务被分为两种,一种宏任务(MacroTask),一种叫微任务(MicroTask)。

    MacroTask(宏任务)

    • script全部代码、setTimeoutsetInterval

    MicroTask(微任务)

    • Promise、await
    执行栈在执行完同步任务后,查看执行栈是否为空,如果执行栈为空,就会去检查微任务队列是否为空,如果为空的话,就执行宏任务,否则就一次性执行完所有微任务。
    每次单个宏任务执行完毕后,检查微任务队列是否为空,如果不为空的话,会按照先入先出的规则全部执行完微任务后,设置微任务队列为null,然后再执行宏任务,如此循环。
     
     
    运行之前我们需要知道以下几点
      • setTimeout属于宏任务
      • Promise本身是同步的立即执行函数,Promise.then属于微任务
      • async方法执行时,遇到await会立即执行表达式,表达式之后的代码放到微任务执行
    于是我们得到了一下结果:
       script start
       async1 start
       async2
       promise1
       script end
       async1 end
       promise2
       setTimeout
  • 相关阅读:
    一个很实用的css3兼容工具很多属性可以兼容到IE6
    html5 canvas 填充渐变形状
    找到任何形状的中心-总结篇
    html canvas非正方旋转和缩放...写的大多是正方的有人表示一直看正方的看厌了
    把jQuery的类、插件封装成seajs的模块的方法
    那些年实用但被我忘掉javascript属性.onresize
    总有一些实用javascript的元素被人遗忘在角落-slice
    jquery(入门篇)无缝滚动
    html5 canvas旋转+缩放
    今天看到这篇新闻之后,决定休息一下咯
  • 原文地址:https://www.cnblogs.com/wujiaqi/p/12389750.html
Copyright © 2011-2022 走看看