【JS基础】关于事件循环的一道题目

发布时间 2023-06-15 21:23:31作者: zjy4fun
const myObject = {
    foo: 'hello',

    func: function () {
        const self = this
        console.log(1, this.foo)
        console.log(2, self.foo)

        function a() {
            console.log(3, this.foo)

            setTimeout(function() {
                const p = new Promise(resolve => {
                    console.log(4, this.foo)
                    setTimeout(() => console.log(5, this.foo), 100)

                    resolve(self.foo)
                })

                p.then(e => console.log(6, e))

                console.log(7, this.foo)
                console.log(8, self.foo)
            }, 100)

            Promise.resolve(this.foo).then(e => console.log(9, e))
        }

        const b = () => {
            console.log(10, this.foo)
            console.log(11, self.foo)
        }

        a()
        b()
    },
}

myObject.func()
/*
1 hello
2 hello
3 undefined
10 hello
11 hello
9 undefined
4 undefined
7 undefined
8 hello
6 hello
5 undefined
 */

打印 3 undefined 是因为在函数 function a(){...}中没有绑定特定的上下文,this指向的是最外层(window),没有找到 foo 这个变量。

setTimeout 和 Promise.resolve中的函数会在下一轮事件循环中执行,所以先执行 b() 中的代码 

Promise.resolve().then()是一个微任务,会优先于setTimeout这个宏任务,所以先打印 9, 由于this指向最外层,所以没有找到 foo 变量,打印 undefined

100毫秒后执行 new Promise,构造函数中会先打印4,里面的 setTimeout 会作为一个宏任务加入到队列,等待下一轮执行

p.then是一个微任务,加入队列,下一轮执行;

打印7 和 8;

这轮事件循环结束,开始下一轮事件循环,先从微任务开始,打印 6;

微任务结束,开始执行宏任务,最里面的 setTimeout 开始执行,打印 5

 

结束!!