《浏览器事件循环机制(EventLoop)代码示例》


2020-08-04 上次更新时间:3/10/2021, 4:57:13 PM 0 javascript

传送门:《并发模型与事件循环》

# 1.在微任务中创建微任务

setTimeout(()=> {
    console.log('setTimeout')
})

new Promise(resolve => {
    resolve()
    console.log('Promise1')
}).then(()=> {
    console.log('Promise1 then')
    Promise.resolve().then(() => {
        console.log('Promise2 then')
    }).then(() => {
        Promise.resolve().then(() => {
        console.log('promise3 then')
        })
    })
})

console.log('end')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 2.微任务队列中创建宏任务

new Promise((resolve) => {
    console.log('new Promise(macro task 1)');
    resolve();
}).then(() => {
    console.log('micro task 1');
    setTimeout(() => {
        console.log('setTimeout1');
    }, 0)
})

setTimeout(() => {
  console.log('setTimeout2');
}, 500)

console.log('end');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 3.宏任务中创建微任务

setTimeout(() => {
    console.log('timer_1');
    setTimeout(() => {
        console.log('timer_3')
    }, 0) 
    new Promise(resolve => {
        resolve()
        console.log('new promise')
    }).then(() => {
        console.log('promise then')
    })
}, 0)

setTimeout(() => {
  console.log('timer_2')
}, 0)

console.log('end')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 4.事件冒泡+事件循环

<div class="outer">
    <div class="inner"></div>
</div>

var outer = document.querySelector('.outer');
var inner = document.querySelector('.inner');

function onClick() {
    console.log('inner');

    setTimeout(function () {
        console.log('inner-timeout');
    }, 0);

    Promise.resolve().then(function () {
        console.log('inner-promise');
    });
}
function onClick2() {
    console.log('outer');

    setTimeout(function () {
        console.log('outer-timeout');
    }, 0);

    Promise.resolve().then(function () {
        console.log('outer-promise');
    });
}

inner.addEventListener('click', onClick);
outer.addEventListener('click', onClick2);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

# 5.async+await

  • async 返回的是一个promise generator + co
  • await => yield 如果产出的是一个promise 会调用这个promise.then方法
async function f1() {
    await f2()
    console.log('f1结束')
}
async function f2() {
    await f3()
    console.log('f2结束')
}
async function f3() {
    console.log('f3结束')
}

f1()

new Promise(res=>{
    console.log('new Promise')
    res()
}).then(res=>{
    console.log('promise第一个then')
}).then(res=>{
    console.log('promise第二个then')
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

await 可以改用 promise

async function f1() {
    //await f2()
    //console.log('f1结束')
    new Promise((resolv,reject)=>resolve(f2())).then(()=>{
    console.log('f1结束')
})
}
async function f2() {
    //await f3()
    //console.log('f2结束')
    new Promise((resolv,reject)=>resolve(f3())).then(()=>{
    console.log('f2结束')
})
}
async function f3() {
    console.log('f3结束')
}

f1()

new Promise(res=>{
    console.log('new Promise')
    res()
}).then(res=>{
    console.log('promise第一个then')
}).then(res=>{
    console.log('promise第二个then')
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 6.混合案例1

console.log('1');

setTimeout(function() {
    console.log('2');
    Promise.resolve().then(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})

Promise.resolve().then(function() {
    console.log('6');
})

new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
    Promise.resolve().then(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# 7.混合案例2

setTimeout(() => { 
    queueMicrotask(() => {
        console.log(1)
    });
    console.log(2)
}, 0)

console.log(3)

queueMicrotask(() => {
    console.log(4)
});

console.log(5)

async1();
async function async1() {
    console.log(6);
    await  async2();
    await  async2();
    console.log(7);
}

async function async2() {
   console.log(8);
}

Promise.resolve().then(() => {
    setTimeout(() => { 
        console.log(9)
    }, 0);
    console.log(10)
}).then(() => {
    console.log(11)
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 8.混合案例3

async function async1() {
    console.log(1);
    await  async2();
    await  async2();
    await  async2();
    console.log(2);
}
async function async2() {
   console.log(3);
}

console.log(4);

setTimeout(function () {
    console.log(5);
    new Promise(function (resolve) {
        console.log(6);
        resolve();
    }).then(function () {
        console.log(7);
    }).then(function() {
        console.log(8)
    });
},0);

async1();

new Promise(function (resolve) {
    console.log(9);
    resolve();
}).then(function () {
    console.log(10);
}).then(function() {
    console.log(11)
});

console.log(12);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
上次更新时间: 3/10/2021, 4:57:13 PM