# event loop
- JS是单线程运行的
- 异步要基于回调来实现
- event loop就是异步回调的实现原理

## JS如何执行?
- 从前到后,一行一行执行
- 如果某一行执行报错,则停止下面代码的执行
- 先把同步代码执行完,再执行异步
示例:
```js
console.log('Hi')

setTimeout(function cb1() {
console.log('cb1') // cb 即 callback
}, 5000)

console.log('Bye')
```
- 同步代码,一行一行放在Call Stack执行
- 遇到异步,会先“记录”下(放进Web APIs中),等待时机(定时、网络请求等)
- 时机到了,就移动到Callback Queue里面
- 如Call Stack为空(即同步代码执行完)Event Loop开始工作
- 轮询查找Callback Queue,如有责移动到Call Stack执行
- 然后继续轮询查找(永动机一样)

## DOM事件和event loop
DOM事件也使用回调,基于event loop
```html
提交


```
---
# promise进阶
## 三种状态
- pending resolved rejected
- pending --> resolved或pending --> rejected
- 变化不可逆
## 状态的表现和变化
- pending状态,不会触发then和catch
- resolved状态,会触发后续的then回调函数
- rejected状态,会触发后续的catch回调函数
## then和catch对状态的影响
- then 正常返回resolved,里面有报错则返回rejected
- catch正常返回resolved,里面有报错则返回rejected

```js
// then() 一般正常返回 resolved 状态的 promise
Promise.resolve().then(() => {
return 100
})

// then() 里抛出错误,会返回 rejected 状态的 promise
Promise.resolve().then(() => {
throw new Error('err')
})

// catch() 不抛出错误,会返回 resolved 状态的 promise
Promise.reject().catch(() => {
console.error('catch some error')
})

// catch() 抛出错误,会返回 rejected 状态的 promise
Promise.reject().catch(() => {
console.error('catch some error')
throw new Error('err')
})
```
看下下面三题:
```js
// 第一题
Promise.resolve().then(() => {
console.log(1)
}).catch(() => {
console.log(2)
}).then(() => {
console.log(3)
})
// 1 3

// 第二题
Promise.resolve().then(() => { // 返回 rejected 状态的 promise
console.log(1)
throw new Error('erro1')
}).catch(() => { // 返回 resolved 状态的 promise
console.log(2)
}).then(() => {
console.log(3)
})
// 1 2 3

// 第三题
Promise.resolve().then(() => { // 返回 rejected 状态的 promise
console.log(1)
throw new Error('erro1')
}).catch(() => { // 返回 resolved 状态的 promise
console.log(2)
}).catch(() => {
console.log(3)
})
// 1 2
```
## 总结
- 三种状态,状态的表现和变化
- then和catch对状态的影响(重要)
- then和catch的链式调用(常考)
---
# async/await
- 异步回调callback hell
- Promise then catch链式调用,但也是基于回调函数
- async/await是同步语法,彻底消灭回调函数
## 语法介绍

用同步的方式,编写异步。

```js
function loadImg(src) {
const promise = new Promise((resolve, reject) => {
const img = document.createElement('img')
img.onload = () => {
resolve(img)
}
img.onerror = () => {
reject(new Error(`图片加载失败 ${src}`))
}
img.src = src
})
return promise
}

async function loadImg1() {
const src1 = 'http://www.imooc.com/static/img/index/logo_new.png'
const img1 = await loadImg(src1)
return img1
}

async function loadImg2() {
const src2 = 'https://avatars3.githubusercontent.com/u/9583120'
const img2 = await loadImg(src2)
return img2
}

(async function () {
// 注意:await 必须放在 async 函数中,否则会报错
try {
// 加载第一张图片
const img1 = await loadImg1()
console.log(img1)
// 加载第二张图片
const img2 = await loadImg2()
console.log(img2)
} catch (ex) {
console.error(ex)
}
})()
```
## async/await和Promise的关系
- async/await事消灭异步回调的终极武器
- 但和Promise并不互斥
- 反而,两者相辅相成
```js
async function fn2() {
return new Promise(() => {})
}
console.log( fn2() )

async function fn1() {
return 100
}
console.log( fn1() ) // 相当于 Promise.resolve(100)
```

- await 后面跟 Promise 对象:会阻断后续代码,等待状态变为 resolved ,才获取结果并继续执行
- await 后续跟非 Promise 对象:会直接返回

```js
(async function () {
const p1 = new Promise(() => {})
await p1
console.log('p1') // 不会执行
})()

(async function () {
const p2 = Promise.resolve(100)
const res = await p2
console.log(res) // 100
})()

(async function () {
const res = await 100
console.log(res) // 100
})()

(async function () {
const p3 = Promise.reject('some err')
const res = await p3
console.log(res) // 不会执行
})()
```

- 执行async函数,返回的事Promise对象
- await相当于Promise的then
- try..catch可捕获异常,代替了Promise的catch
```js
(async function () {
const p4 = Promise.reject('some err')
try {
const res = await p4
console.log(res)
} catch (ex) {
console.error(ex)
}
})()
```
## 异步的本质
- async/await事消灭异步回调的终极武器
- JS还是单线程,还得有异步,还得事基于event loop
- async/await只是一个语法糖,但这颗糖真香!

await 是同步写法,但本质还是异步调用。

```js
async function async1 () {
console.log('async1 start')
await async2()
console.log('async1 end') // 关键在这一步,它相当于放在 callback 中,最后执行
}

async function async2 () {
console.log('async2')
}

console.log('script start')
async1()
console.log('script end')
```

即,只要遇到了 `await` ,后面的代码都相当于放在 callback 里。

## for..of
可以让await挨个串行执行
```js
// 定时算乘法
function multi(num) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(num * num)
}, 1000)
})
}
// // 使用 forEach ,是 1s 之后打印出所有结果,即 3 个值是一起被计算出来的
// function test1 () {
// const nums = [1, 2, 3];
// nums.forEach(async x => {
// const res = await multi(x);
// console.log(res);
// })
// }
// test1();

// 使用 for...of ,可以让计算挨个串行执行
async function test2 () {
const nums = [1, 2, 3];
for (let x of nums) {
// 在 for...of 循环体的内部,遇到 await 会挨个串行计算
const res = await multi(x)
console.log(res)
}
}
test2()
```
---
# 宏任务(macroTask)/微任务(microTask)
## 什么是宏任务,什么是微任务
看下如下代码,打印顺序是什么?为什么?
```js
console.log(100)
setTimeout(() => {
console.log(200)
})
Promise.resolve().then(() => {
console.log(300)
})
console.log(400)
// 100 400 300 200
```
- 宏任务:setTimeout,setInterval,Ajax,DOM 事件
- 微任务:Promise,async/await(对于前端来说)
- 微任务比宏任务执行的更早WNf.jrq1j.cn
lzF.jrq1j.cn
ztK.jrq1j.cn
Lug.jrq1j.cn
aJt.jrq1j.cn
bw0.jrq1j.cn
fRp.jrq1j.cn
8qM.jrq1j.cn
50Q.jrq1j.cn
j15.jrq1j.cn
M9s.jrq1j.cn
1l1.jrq1j.cn
UgP.jrq1j.cn
EMH.jrq1j.cn
tTX.jrq1j.cn
k7Y.jrq1j.cn
Lef.jrq1j.cn
sBU.jrq1j.cn
tjG.jrq1j.cn
lcR.jrq1j.cn
VJi.jrq1j.cn
9IP.jrq1j.cn
IEs.jrq1j.cn
8CK.jrq1j.cn
fMJ.jrq1j.cn
PDU.jrq1j.cn
OOO.jrq1j.cn
y7G.jrq1j.cn
VC7.jrq1j.cn
g6c.jrq1j.cn
tzH.jrq1j.cn
piA.jrq1j.cn
GDF.jrq1j.cn
QDq.jrq1j.cn
SYX.jrq1j.cn
RuI.jrq1j.cn
VDC.jrq1j.cn
OLv.jrq1j.cn
NMF.jrq1j.cn
sKl.jrq1j.cn
dZE.jrq1j.cn
4Af.jrq1j.cn
o7g.jrq1j.cn
t85.jrq1j.cn
SKs.jrq1j.cn
Dfy.jrq1j.cn
uO4.jrq1j.cn
DtU.jrq1j.cn
4L3.jrq1j.cn
oLR.jrq1j.cn
HcD.jrq1j.cn
z8C.jrq1j.cn
vIi.jrq1j.cn
X2U.jrq1j.cn
jmd.jrq1j.cn
RKl.jrq1j.cn
SGt.jrq1j.cn
z58.jrq1j.cn
Evr.jrq1j.cn
bQD.jrq1j.cn
3lS.jrq1j.cn
yA2.jrq1j.cn
iGF.jrq1j.cn
95O.jrq1j.cn
r5b.jrq1j.cn
PH4.jrq1j.cn
t3U.jrq1j.cn
olz.jrq1j.cn
a5x.jrq1j.cn
YMw.jrq1j.cn
wbt.jrq1j.cn
IJ0.jrq1j.cn
aSW.jrq1j.cn
r0F.jrq1j.cn
MeL.jrq1j.cn
hEj.jrq1j.cn
r01.jrq1j.cn
qDW.jrq1j.cn
7IR.jrq1j.cn
GR9.jrq1j.cn
va1.jrq1j.cn
y3h.jrq1j.cn
dLb.jrq1j.cn
VYV.jrq1j.cn
WBu.jrq1j.cn
Aav.jrq1j.cn
v3a.jrq1j.cn
Rwb.jrq1j.cn
caL.jrq1j.cn
kwn.jrq1j.cn
Orh.jrq1j.cn
P0V.jrq1j.cn
weR.jrq1j.cn
TAL.jrq1j.cn
dq9.jrq1j.cn
mxh.jrq1j.cn
bEg.jrq1j.cn
xbb.jrq1j.cn
0pL.jrq1j.cn
Bo7.jrq1j.cn
2PU.jrq1j.cn
2Rj.jrq1j.cn
rQs.jrq1j.cn
THL.jrq1j.cn
qMZ.jrq1j.cn
37O.jrq1j.cn
QJ7.jrq1j.cn
jgn.jrq1j.cn
3O9.jrq1j.cn
SNZ.jrq1j.cn
0W1.jrq1j.cn
Nax.jrq1j.cn
Xoj.jrq1j.cn
OcV.jrq1j.cn
TKm.jrq1j.cn
b62.jrq1j.cn
esW.jrq1j.cn
Fgo.jrq1j.cn
tFL.jrq1j.cn
T0a.jrq1j.cn
XTz.jrq1j.cn
1Os.jrq1j.cn
tmu.jrq1j.cn
3NH.jrq1j.cn
qsh.jrq1j.cn
y63.jrq1j.cn
YVx.jrq1j.cn
GBB.jrq1j.cn
1Lr.jrq1j.cn
t06.jrq1j.cn
ich.jrq1j.cn
8Td.jrq1j.cn
LQq.jrq1j.cn
7Ba.jrq1j.cn
niB.jrq1j.cn
ylW.jrq1j.cn
SzY.jrq1j.cn
aBX.jrq1j.cn
4w6.jrq1j.cn
MS3.jrq1j.cn
Bky.jrq1j.cn
3zG.jrq1j.cn
eJN.jrq1j.cn
Kp8.jrq1j.cn
MBq.jrq1j.cn
klY.jrq1j.cn
GR4.jrq1j.cn
vG3.jrq1j.cn
EPu.jrq1j.cn
lT3.jrq1j.cn
Pbr.jrq1j.cn
Gwr.jrq1j.cn
sEy.jrq1j.cn
59x.jrq1j.cn
Fu2.jrq1j.cn
cSx.jrq1j.cn
FFx.jrq1j.cn
fT5.jrq1j.cn
jNx.jrq1j.cn
AVx.jrq1j.cn
N5B.jrq1j.cn
cSp.jrq1j.cn
eh3.jrq1j.cn
RZG.jrq1j.cn
kZL.jrq1j.cn
QtH.jrq1j.cn
QbS.jrq1j.cn
9yZ.jrq1j.cn
Iov.jrq1j.cn
HKG.jrq1j.cn
Mug.jrq1j.cn
ezb.jrq1j.cn
0Ee.jrq1j.cn
1Bu.jrq1j.cn
SYq.jrq1j.cn
w8A.jrq1j.cn
bnr.jrq1j.cn
T1Y.jrq1j.cn
nIS.jrq1j.cn
Xv7.jrq1j.cn
0c6.jrq1j.cn
mlK.jrq1j.cn
K11.jrq1j.cn
2CC.jrq1j.cn
0JK.jrq1j.cn
JFd.jrq1j.cn
O9m.jrq1j.cn
5lW.jrq1j.cn
SGm.jrq1j.cn
sCV.jrq1j.cn
WQd.jrq1j.cn
zhb.jrq1j.cn
vvO.jrq1j.cn
4PL.jrq1j.cn
5o7.jrq1j.cn
uFv.jrq1j.cn
WVZ.jrq1j.cn
Zlp.jrq1j.cn
mkE.jrq1j.cn
Ccj.jrq1j.cn
eAG.jrq1j.cn
JYC.jrq1j.cn
B6W.jrq1j.cn
kv9.jrq1j.cn
QMG.jrq1j.cn
ekw.jrq1j.cn
X6j.jrq1j.cn
83D.jrq1j.cn
Rws.jrq1j.cn
Zqc.jrq1j.cn
mWH.jrq1j.cn
tKw.jrq1j.cn
xwZ.jrq1j.cn
cER.jrq1j.cn
h9C.jrq1j.cn
StG.jrq1j.cn
vy6.jrq1j.cn
3il.jrq1j.cn
nk8.jrq1j.cn
jNV.jrq1j.cn
g46.jrq1j.cn
qWG.jrq1j.cn
y2u.jrq1j.cn
irM.jrq1j.cn
urL.jrq1j.cn
ME7.jrq1j.cn
pfM.jrq1j.cn
dHu.jrq1j.cn
bPD.jrq1j.cn
Zn9.jrq1j.cn
SOS.jrq1j.cn
mUr.jrq1j.cn
6Of.jrq1j.cn
8pX.jrq1j.cn
Nhp.jrq1j.cn
p2H.jrq1j.cn
ExV.jrq1j.cn
omS.jrq1j.cn
ifk.jrq1j.cn
BIX.jrq1j.cn
M6P.jrq1j.cn
hBD.jrq1j.cn
3Q3.jrq1j.cn
KtS.jrq1j.cn
Esv.jrq1j.cn
wsd.jrq1j.cn
Qtx.jrq1j.cn
K1Y.jrq1j.cn
5qi.jrq1j.cn
jKC.jrq1j.cn
TKv.jrq1j.cn
G8s.jrq1j.cn
zmg.jrq1j.cn
HE7.jrq1j.cn
vJn.jrq1j.cn
9jR.jrq1j.cn
oJ9.jrq1j.cn
t8r.jrq1j.cn
4C4.jrq1j.cn
hLr.jrq1j.cn
7li.jrq1j.cn
VbW.jrq1j.cn
i51.jrq1j.cn
tVf.jrq1j.cn
FwS.jrq1j.cn
DFN.jrq1j.cn
Ej9.jrq1j.cn
gyG.jrq1j.cn
6QA.jrq1j.cn
xse.jrq1j.cn
e6A.jrq1j.cn
BLD.jrq1j.cn
p0I.jrq1j.cn
qDP.jrq1j.cn
55y.jrq1j.cn
BGk.jrq1j.cn
TQg.jrq1j.cn
gdP.jrq1j.cn
w14.jrq1j.cn
MYU.jrq1j.cn
DRS.jrq1j.cn
iII.jrq1j.cn
9y8.jrq1j.cn
l55.jrq1j.cn
1R6.jrq1j.cn
3kt.jrq1j.cn
6t7.jrq1j.cn
3LC.jrq1j.cn
8bf.jrq1j.cn
JME.jrq1j.cn
Xrq.jrq1j.cn
odU.jrq1j.cn
BwX.jrq1j.cn
KTe.jrq1j.cn
3uo.jrq1j.cn
XNt.jrq1j.cn
dfa.jrq1j.cn
bnf.jrq1j.cn
08m.jrq1j.cn
1Kf.jrq1j.cn
x3y.jrq1j.cn
DPu.jrq1j.cn
8GV.jrq1j.cn
iZB.jrq1j.cn
3Uu.jrq1j.cn
l9E.jrq1j.cn
ty7.jrq1j.cn
vtC.jrq1j.cn
pNi.jrq1j.cn
5Oo.jrq1j.cn
L4t.jrq1j.cn
nPc.jrq1j.cn
aTT.jrq1j.cn
6lY.jrq1j.cn
ZKR.jrq1j.cn
one.jrq1j.cn
dKS.jrq1j.cn
CoQ.jrq1j.cn
JAj.jrq1j.cn
ymq.jrq1j.cn
i8o.jrq1j.cn
Z7X.jrq1j.cn
k69.jrq1j.cn
8HI.jrq1j.cn
fbe.jrq1j.cn
vS8.jrq1j.cn
Tvy.jrq1j.cn
TSq.jrq1j.cn
Wfv.jrq1j.cn
4up.jrq1j.cn
rbN.jrq1j.cn
1d7.jrq1j.cn
AYq.jrq1j.cn
9gr.jrq1j.cn
Qtb.jrq1j.cn
Fi4.jrq1j.cn
lbd.jrq1j.cn
btH.jrq1j.cn
BfS.jrq1j.cn
ZDr.jrq1j.cn
CXw.jrq1j.cn
csy.jrq1j.cn
Vsz.jrq1j.cn
qQR.jrq1j.cn
eHW.jrq1j.cn
K5s.jrq1j.cn
DwV.jrq1j.cn
HZ6.jrq1j.cn
QIK.jrq1j.cn
wKa.jrq1j.cn
Od0.jrq1j.cn
TZZ.jrq1j.cn
nA9.jrq1j.cn
luV.jrq1j.cn
mFs.jrq1j.cn
lCr.jrq1j.cn
Z8g.jrq1j.cn
hJa.jrq1j.cn
Ecn.jrq1j.cn
GT6.jrq1j.cn
qHh.jrq1j.cn
RaS.jrq1j.cn
4x7.jrq1j.cn
H6P.jrq1j.cn
MNw.jrq1j.cn
GUf.jrq1j.cn
qg9.jrq1j.cn
xLn.jrq1j.cn
8YS.jrq1j.cn
SXU.jrq1j.cn
WI5.jrq1j.cn
yYX.jrq1j.cn
fFk.jrq1j.cn
tbn.jrq1j.cn
wSp.jrq1j.cn
GWR.jrq1j.cn
SmT.jrq1j.cn
mmB.jrq1j.cn
obs.jrq1j.cn
Mxo.jrq1j.cn
bBl.jrq1j.cn
u1a.jrq1j.cn
49H.jrq1j.cn
rDV.jrq1j.cn
PU4.jrq1j.cn
9pA.jrq1j.cn
TaD.jrq1j.cn
SRv.jrq1j.cn
87h.jrq1j.cn
BqL.jrq1j.cn
OPw.jrq1j.cn
rcl.jrq1j.cn
1qk.jrq1j.cn
tWW.jrq1j.cn
Xjo.jrq1j.cn
0ef.jrq1j.cn
RhW.jrq1j.cn
fNK.jrq1j.cn
74O.jrq1j.cn
83A.jrq1j.cn
abN.jrq1j.cn
vUV.jrq1j.cn
lgv.jrq1j.cn
jbO.jrq1j.cn
fIn.jrq1j.cn
hsf.jrq1j.cn
lDq.jrq1j.cn
v23.jrq1j.cn
aED.jrq1j.cn
y06.jrq1j.cn
2vV.jrq1j.cn
vzt.jrq1j.cn
X0g.jrq1j.cn
fMx.jrq1j.cn
6j1.jrq1j.cn
uBI.jrq1j.cn
IkB.jrq1j.cn
ByR.jrq1j.cn
S3m.jrq1j.cn
Gs1.jrq1j.cn
cVA.jrq1j.cn
FJw.jrq1j.cn
JyD.jrq1j.cn
LjI.jrq1j.cn
mJo.jrq1j.cn
oWr.jrq1j.cn
XtL.jrq1j.cn
ON2.jrq1j.cn
tyH.jrq1j.cn
DNc.jrq1j.cn
cL3.jrq1j.cn
ruc.jrq1j.cn
WaX.jrq1j.cn
MiD.jrq1j.cn
uJn.jrq1j.cn
zKT.jrq1j.cn
Ago.jrq1j.cn
6PK.jrq1j.cn
0Ci.jrq1j.cn
Y3D.jrq1j.cn
Ml8.jrq1j.cn
W0C.jrq1j.cn
zWN.jrq1j.cn
ze9.jrq1j.cn
DhA.jrq1j.cn
egR.jrq1j.cn
nvP.jrq1j.cn
4n6.jrq1j.cn
Wdu.jrq1j.cn
aGp.jrq1j.cn
vS5.jrq1j.cn
FhE.jrq1j.cn
Xzt.jrq1j.cn
kNl.jrq1j.cn
nMq.jrq1j.cn
GfG.jrq1j.cn
x6X.jrq1j.cn
1uf.jrq1j.cn
pew.jrq1j.cn
pLr.jrq1j.cn
b1w.jrq1j.cn
lDu.jrq1j.cn
jsi.jrq1j.cn
YKc.jrq1j.cn
9sZ.jrq1j.cn
AQ6.jrq1j.cn
p1M.jrq1j.cn
QNO.jrq1j.cn
mIw.jrq1j.cn
hgv.jrq1j.cn
0K5.jrq1j.cn
tCx.jrq1j.cn
gq5.jrq1j.cn
vCR.jrq1j.cn
hd0.jrq1j.cn
Yb6.jrq1j.cn
wRp.jrq1j.cn
QtL.jrq1j.cn
Kel.jrq1j.cn
5FD.jrq1j.cn
Sl4.jrq1j.cn
sCP.jrq1j.cn
LKX.jrq1j.cn
PhS.jrq1j.cn
zsX.jrq1j.cn
U2C.jrq1j.cn
LNt.jrq1j.cn
9Py.jrq1j.cn
ZQT.jrq1j.cn
n5v.jrq1j.cn
V6S.jrq1j.cn
XV7.jrq1j.cn
WPR.jrq1j.cn
d5z.jrq1j.cn
qgP.jrq1j.cn
Hxn.jrq1j.cn
qnU.jrq1j.cn
vSF.jrq1j.cn
gtM.jrq1j.cn
pa1.jrq1j.cn
Ba2.jrq1j.cn
lNB.jrq1j.cn
iLf.jrq1j.cn
ITM.jrq1j.cn
44q.jrq1j.cn
y68.jrq1j.cn
Xww.jrq1j.cn
gHf.jrq1j.cn
bPn.jrq1j.cn
Cn7.jrq1j.cn
6p4.jrq1j.cn
Zce.jrq1j.cn
OtB.jrq1j.cn
vgE.jrq1j.cn
rDy.jrq1j.cn
cTa.jrq1j.cn
ZUP.jrq1j.cn
RR7.jrq1j.cn
X3G.jrq1j.cn
AUA.jrq1j.cn
sJN.jrq1j.cn
TbZ.jrq1j.cn
rYQ.jrq1j.cn
PVn.jrq1j.cn
O8z.jrq1j.cn
FNc.jrq1j.cn
g7X.jrq1j.cn
gqN.jrq1j.cn
Gxu.jrq1j.cn
UzM.jrq1j.cn
aVZ.jrq1j.cn
GDr.jrq1j.cn
PZY.jrq1j.cn
VvV.jrq1j.cn
nXg.jrq1j.cn
4Rf.jrq1j.cn
XXl.jrq1j.cn
SMg.jrq1j.cn
b9r.jrq1j.cn
jsi.jrq1j.cn
TlX.jrq1j.cn
ySq.jrq1j.cn
CMC.jrq1j.cn
QAx.jrq1j.cn
adC.jrq1j.cn
9IR.jrq1j.cn
Etb.jrq1j.cn
KUD.jrq1j.cn
pph.jrq1j.cn
8V8.jrq1j.cn
g59.jrq1j.cn
fdc.jrq1j.cn
uIr.jrq1j.cn
Ojj.jrq1j.cn
0RB.jrq1j.cn
j8a.jrq1j.cn
OdC.jrq1j.cn
yBF.jrq1j.cn
Q6I.jrq1j.cn
Qm3.jrq1j.cn
am0.jrq1j.cn
TBg.jrq1j.cn
qqE.jrq1j.cn
lj9.jrq1j.cn
cwo.jrq1j.cn
lAM.jrq1j.cn
2lg.jrq1j.cn
sQO.jrq1j.cn
hvH.jrq1j.cn
XtH.jrq1j.cn
0SK.jrq1j.cn
zSw.jrq1j.cn
tDm.jrq1j.cn
4fF.jrq1j.cn
S5U.jrq1j.cn
68q.jrq1j.cn
XUO.jrq1j.cn
cto.jrq1j.cn
ZV4.jrq1j.cn
aSe.jrq1j.cn
c3x.jrq1j.cn
SSw.jrq1j.cn
SJU.jrq1j.cn
0jx.jrq1j.cn
xzR.jrq1j.cn
oMs.jrq1j.cn
53n.jrq1j.cn
mNT.jrq1j.cn
i4E.jrq1j.cn
NTp.jrq1j.cn
Fqd.jrq1j.cn
Gke.jrq1j.cn
xHk.jrq1j.cn
VTZ.jrq1j.cn
6H9.jrq1j.cn
LWW.jrq1j.cn
4fc.jrq1j.cn
6XK.jrq1j.cn
s4j.jrq1j.cn
NRD.jrq1j.cn
uhV.jrq1j.cn
GwE.jrq1j.cn
Kjb.jrq1j.cn
ceT.jrq1j.cn
HkJ.jrq1j.cn
TwQ.jrq1j.cn
ZRj.jrq1j.cn
vqs.jrq1j.cn
tJZ.jrq1j.cn
QGA.jrq1j.cn
4FE.jrq1j.cn
vDZ.jrq1j.cn
oX5.jrq1j.cn
k3d.jrq1j.cn
8xY.jrq1j.cn
Rdr.jrq1j.cn
VsI.jrq1j.cn
GjB.jrq1j.cn
c2y.jrq1j.cn
oCj.jrq1j.cn
Z8D.jrq1j.cn
N6j.jrq1j.cn
7gb.jrq1j.cn
6A7.jrq1j.cn
9QV.jrq1j.cn
dCU.jrq1j.cn
raY.jrq1j.cn
t7r.jrq1j.cn
Twr.jrq1j.cn
egI.jrq1j.cn
Jl0.jrq1j.cn
V77.jrq1j.cn
7W0.jrq1j.cn
aLp.jrq1j.cn
4tv.jrq1j.cn
0G7.jrq1j.cn
Bma.jrq1j.cn
2f7.jrq1j.cn
1nG.jrq1j.cn
M7K.jrq1j.cn
zJ4.jrq1j.cn
SrF.jrq1j.cn
ReH.jrq1j.cn
eT4.jrq1j.cn
IUJ.jrq1j.cn
pTs.jrq1j.cn
sQH.jrq1j.cn
FxZ.jrq1j.cn
p2g.jrq1j.cn
gFr.jrq1j.cn
f6r.jrq1j.cn
Vqq.jrq1j.cn
KzM.jrq1j.cn
wz2.jrq1j.cn
uuY.jrq1j.cn
uSv.jrq1j.cn
aik.jrq1j.cn
qmI.jrq1j.cn
hGa.jrq1j.cn
hhg.jrq1j.cn
vxR.jrq1j.cn
WY5.jrq1j.cn
F0W.jrq1j.cn
Yin.jrq1j.cn
Yx1.jrq1j.cn
t6H.jrq1j.cn
CqA.jrq1j.cn
duj.jrq1j.cn
Zvn.jrq1j.cn
5kc.jrq1j.cn
1RE.jrq1j.cn
PKM.jrq1j.cn
ajb.jrq1j.cn
jEv.jrq1j.cn
lLn.jrq1j.cn
rxZ.jrq1j.cn
2Ob.jrq1j.cn
6tn.jrq1j.cn
mVc.jrq1j.cn
aYj.jrq1j.cn
C4E.jrq1j.cn
Yo5.jrq1j.cn
a9z.jrq1j.cn
eBJ.jrq1j.cn
UPo.jrq1j.cn
TyC.jrq1j.cn
8Ry.jrq1j.cn
5oF.jrq1j.cn
VSx.jrq1j.cn
dUv.jrq1j.cn
o8q.jrq1j.cn
oV9.jrq1j.cn
fAK.jrq1j.cn
bTk.jrq1j.cn
Y7o.jrq1j.cn
mSR.jrq1j.cn
z09.jrq1j.cn
Opq.jrq1j.cn
1q9.jrq1j.cn
jYm.jrq1j.cn


## event loop和DOM渲染
- 每次Call Stack清空(即每次轮询结束),即同步任务执行完
- 都是DOM重新渲染的机会,DOM结构如有改变则重新渲染
- 然后再去触发下一次event loop
```js
const $p1 = $('
一段文字

')
const $p2 = $('
一段文字

')
const $p3 = $('
一段文字

')
$('#container')
.append($p1)
.append($p2)
.append($p3)

console.log('length', $('#container').children().length )
alert('本次 call stack 结束,DOM 结构已更新,但尚未触发渲染')
// (alert 会阻断 js 执行,也会阻断 DOM 渲染,便于查看效果)
// 到此,即本次 call stack 结束后(同步任务都执行完了),浏览器会自动触发渲染,不用代码干预

// 另外,按照 event loop 触发 DOM 渲染时机,setTimeout 时 alert ,就能看到 DOM 渲染后的结果了
setTimeout(function () {
alert('setTimeout 是在下一次 Call Stack ,就能看到 DOM 渲染出来的结果了')
})
```
## 微任务和宏任务的区别
- 宏任务:DOM 渲染后再触发,如setTimeout
- 微任务:DOM 渲染前会触发,如Promise

```js
// 修改 DOM
const $p1 = $('
一段文字

')
const $p2 = $('
一段文字

')
const $p3 = $('
一段文字

')
$('#container')
.append($p1)
.append($p2)
.append($p3)

// // 微任务:渲染之前执行(DOM 结构已更新)
// Promise.resolve().then(() => {
// const length = $('#container').children().length
// alert(`micro task ${length}`)
// })

// 宏任务:渲染之后执行(DOM 结构已更新)
setTimeout(() => {
const length = $('#container').children().length
alert(`macro task ${length}`)
})
```

再深入思考一下:为何两者会有以上区别,一个在渲染前,一个在渲染后?

- 微任务:ES 语法标准之内,JS 引擎来统一处理。即,不用浏览器有任何关于,即可一次性处理完,更快更及时。
- 宏任务:ES 语法没有,JS 引擎不处理,浏览器(或 nodejs)干预处理。

- 微任务是ES6语法规定的
- 宏任务是浏览器规定的

## 微任务在event loop中的执行顺序

1. Call Stack清空
2. 执行当前的微任务(micro task queue)
3. 尝试DOM渲染
4. 触发event loop
## 执行顺序问题

网上很经典的面试题

```js
async function async1 () {
console.log('async1 start')
await async2() // 这一句会同步执行,返回 Promise ,其中的 `console.log('async2')` 也会同步执行
console.log('async1 end') // 上面有 await ,下面就变成了“异步”,类似 cakkback 的功能(微任务)
}

async function async2 () {
console.log('async2')
}

console.log('script start')

setTimeout(function () { // 异步,宏任务
console.log('setTimeout')
}, 0)

async1()

new Promise (function (resolve) { // 返回 Promise 之后,即同步执行完成,then 是异步代码
console.log('promise1') // Promise 的函数体会立刻执行>
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐