zoukankan      html  css  js  c++  java
  • 事件循环

    宏任务:setTimeout/setImmediate

    微任务:Promise

    浏览器: 执行一个宏任务,执行所有微任务

    node:先执行所有宏任务,再执行微任务

    function test() {
        console.log('start')
        setTimeout(() => {
            console.log('children2')
            Promise.resolve().then(() => { console.log('children2-1') })
        }, 0)
        setTimeout(() => {
            console.log('children3')
            Promise.resolve().then(() => { console.log('children3-1') })
        }, 0)
        Promise.resolve()
            .then(() => {
                console.log('children1')
            }).then(() => {
                console.log('children1-1')
            })
        console.log('end')
    }
    
    test()
    
    
    /**
     * 浏览器分析
     * 执行一个宏任务,执行完所有微任务
     * 1.start主线执行,
     * 2.children2添加到宏任务队列
     * 3.children3添加到宏任务队列
     * 4.children1添加到微任务队列
     * 5.children1-1添加到微任务队列
     * 6.end主线执行
     * ------------以上主线任务执行完毕,开始检查微任务----------------
     * 7.微任务队列中有children1,children1-1执行
     * ------------微任务执行完毕,开始检查宏任务-------------------
     * 8.children2排在宏任务队列第一个,执行,并将children2-1添加到微任务中
     * ------------宏任务执行一个,开始执行所有微任务---------------
     * 9.微任务队列只有children2-1,执行
     * ------------微任务执行完毕,开始检查宏任务-------------------
     * 10.宏任务队列第二个为children3,执行,并将children3-1添加到微任务中
     * ------------宏任务执行一个,开始执行所有微任务---------------
     * 11.微任务队列只有children3-1,执行
     * ------------微任务执行完毕,开始检查宏任务,无,检查微任务,无,代码执行完毕-------------------
     */
    
    /**
     * node11以下版本分析
     * 先执行所有的宏任务,再执行微任务
     * 1.start主线执行,
     * 2.children2添加到宏任务队列
     * 3.children3添加到宏任务队列
     * 4.children1添加到微任务队列
     * 5.children1-1添加到微任务队列
     * 6.end主线执行
     * ------------以上主线任务执行完毕,开始检查微任务----------------
     * 7.微任务队列中有children1,children1-1,执行
     * ------------微任务执行完毕,开始检查宏任务-------------------
     * 8.children2排在宏任务队列第一个,执行,并将children2-1添加到微任务中
     * 9.宏任务队列第二个为children3,执行,并将children3-1添加到微任务中
     * ------------宏任务全部执行完毕,开始检查微任务-------------------
     * 10.微任务第一个children2-1,执行
     * 11.微任务第二个children3-1,执行
     * ------------微任务执行完毕,开始检查宏任务,无,检查微任务,无,代码执行完毕-------------------
     */

    有async函数

    async函数,看调用阶段,如

    async function async() {
        console.log(1)
    }
    console.log(2)
    async()
    /**
     * async函数调用在2后面,所以先打印2再打印1
     */

    有await async的调用,如

    async function async1() {
        console.log('async1 start')
        await async2()
        console.log('async1 end')
    }
    
    async function async2() {
        console.log('async2')
    }

    可改写成promise.then便于理解

    async function async1() {
        console.log('async1 start')
        new Promise(function (resolve) {
            console.log('async2')
            resolve()
        }).then(function () {
            console.log('async1 end')
        })
    }

    完整例子:

    async function async1() {
        console.log('async1 start')
        await async2()
        console.log('async1 end')
    }
    
    async function async2() {
        console.log('async2')
    }
    
    console.log('script start')
    
    setTimeout(function () {
        console.log('setTimeOut')
    }, 0)
    
    async1()
    
    new Promise(function (resolve) {
        console.log('promise1')
        resolve()
    }).then(function () {
        console.log('promise2')
    })
    
    console.log('script end')
    
    /**
     * 1、顺序执行,打印script start
     * 2、宏任务队列加入setTimeOut
     * 3、调用async1,打印async1 start
     * 4、调用async2,打印async2
     * 5、微任务队列中加入async1 end
     * 6、打印promise1
     * 7、微任务队列加入promise2
     * 8、打印script end
     * -------------代码执行完毕,此时微任务队列中有async1 end,promise2,宏任务队列中有setTimeOut------------
     * 9、执行所有微任务,打印async1 end,promise2
     * 10、执行宏任务,打印setTimeOut
     * ------结果为script start->async1 start->async2->promise1->script end->async1 end->promise2->setTimeOut----------
     * 因主线任务完成后宏任务队列中只有一个,所以node应该与浏览器打印结果相同(实际并不相同,node中promise2与async1 end打印顺序颠倒了,还没弄懂是怎么回事)
     */
    console.log(1);
    
    setTimeout(() => {
        console.log(2)
    });
    
    Promise.resolve().then(() => {
        console.log(3);
    });
    
    setImmediate(() => {
        console.log(4)
    });
    
    new Promise(resolve => {
        console.log(5);
        resolve();
        console.log(6);
    }).then(() => {
        console.log(7)
    });
    
    Promise.resolve().then(() => {
        console.log(8);
        Promise.resolve().then(() => {  //这里容易产生误解,并不是又一层回调。应该在8后添加入微任务队列
            console.log(9)
        });
    });
    //1 5 6 3 7 8 9 2 4
  • 相关阅读:
    揭秘数字行为:快速地多次点击
    MySQL事务在MGR中的漫游记—路线图
    如何成为一名获客专家?
    10分钟快速构建汽车零售看板
    聊一聊整车厂的那些事——售后配件业务
    网易云易盾牵手百视通 助力广电领域新媒体内容安全
    人工智能热门图书(深度学习、TensorFlow)免费送!
    dubbo异步调用原理 (1)
    dubbo事件通知机制 (2)
    dubbo事件通知机制(1)
  • 原文地址:https://www.cnblogs.com/lianglanlan/p/14420772.html
Copyright © 2011-2022 走看看