js设想为单线程
js设想为单线程照样跟他的用处有关
试想一下 假如js设想为多线程 那末同时修正和删除同一个dom 浏览器又该怎样实行?
js须要异步
for (var i=0;i<9999;i++){
console.log("我在实行 但用户不知道")
}
console.log("你好啊")
上图例子 for轮回耗时会良久
这意味着 用户得不到 ‘你好啊’ 的相应 就会下意识会以为浏览器卡死了 所以js必需要有异步
js经由过程事宜轮回来完成异步 这也是js的运行机制
一方面代码逐步跑着 另一方面用户已抓狂
js事宜轮回 (说白了不停实行俩步骤)
一、归类
碰到同步使命直接实行,碰到异步使命分类为
宏使命(macro-task)
和
微使命(micro-task)
。宏使命:团体的
Script
setTimeout
setInterval
微使命:
Promise
process.nextTick
请看示例代码:
// 这是一个同步使命
console.log('1') --------> 直接被实行
如今打印效果为:1
// 这是一个宏使命
setTimeout(function () { --------> 团体的setTimeout被放进宏使命列表
console.log('2') 如今宏使命列表记为【s2】
});
new Promise(function (resolve) {
// 这里是同步使命
console.log('3'); --------> 直接被实行
resolve(); 如今打印效果为:1、3
// then是一个微使命
}).then(function () { --------> 团体的then[包括内里的setTimeout]被放进微使命列表
console.log('4') 如今微使命列表记为【t45】
setTimeout(function () {
console.log('5')
});
});
第一轮小结:
实行到这里的效果:1、3
宏使命列表以下:
setTimeout(function () {
console.log('2')
});
微使命列表以下:
then(function () {
console.log('4')
setTimeout(function () {
console.log('5')
});
});
二、有微则微,无微则宏
假如微使命列表内里有使命 会实行终了后在实行宏使命 (ps:开篇有流程图)
浏览器瞅了一眼微使命列表 发明内里有微使命 就最先悉数实行
then(function () {
console.log('4') --------> 直接被实行
如今打印效果为:1、3、4
setTimeout(function () { --------> 被放进宏使命列表了
console.log('5') 如今宏使命列表记为【s2、s5】
});
});
浏览器发明微使命实行终了了
最先实行宏使命列表
setTimeout(function () {
console.log('2') --------> 直接被实行
如今打印效果为:1、3、4、2
});
setTimeout(function () {
console.log('5') --------> 直接被实行
如今打印递次为: 1、3、4、2、5、5
});
终究效果为: 1、3、4、2、5
三、总结 + 实战
重复实行以上步骤 就是事宜轮回(event loop)
一定要分的清使命范例 (宏使命 和 微使命)
TIP: 为了轻易分辨起名为p1(p开首 内里打印1)
process.nextTick(function() { --------> 被放微使命列表
console.log('1'); 微使命列表记为:【p1】
})
new Promise(function (resolve) {
console.log('2'); --------> 直接实行
resolve(); 如今打印递次为:2
}).then(function () { --------> 团体的then被放进微使命列表[包括个中的setTimeout 4]
console.log('3'); 微使命列表记为:【p1 t34】
setTimeout(function () {
console.log('4')
});
});
setTimeout(function () { --------> 被放宏使命列表
console.log('5') 宏使命列表记为:【s5】
});
new Promise(function (resolve) {
setTimeout(function () { --------> 被放宏使命列表
console.log('6') 宏使命列表记为:【s5 s6】
});
resolve()
}).then(function () { --------> 团体的then被放进微使命列表[包括个中的setTimeout和个中的多层嵌套]
setTimeout(function () { 微使命列表记为:【p1 t34 t789】
console.log('7')
new Promise(function (resolve) {
setTimeout(function () {
console.log('8')
});
resolve()
}).then(function () {
setTimeout(function () {
console.log('9')
});
});
});
});
console.log('10') --------> 直接实行
如今打印递次为:2、10
第一轮小结:
实行效果为:2、10
宏使命列表以下:
// s5
setTimeout(function () {
console.log('5')
});
//s6
setTimeout(function () {
console.log('6')
});
微使命列表以下:
// p1
process.nextTick(function() {
console.log('1');
})
// t34
then(function () {
console.log('3');
setTimeout(function () {
console.log('4')
});
});
// t789
then(function () {
setTimeout(function () {
console.log('7')
new Promise(function (resolve) {
setTimeout(function () {
console.log('8')
});
resolve()
}).then(function () {
setTimeout(function () {
console.log('9')
});
});
});
最先实行第二轮:
有微使命 先实行微使命
将微使命列表代码块搬下来
// p1
process.nextTick(function() { --------> 实行p1
console.log('1'); 如今打印递次为:2、10、1
})
// t34
then(function () {
console.log('3'); --------> 直接实行
如今打印递次为:2、10、1、3
setTimeout(function () { --------> 被放宏使命列表
console.log('4') 宏使命列表记为:【s5 s6 s4】
});
});
// t789
then(function () {
setTimeout(function () { --------> 被放宏使命列表
console.log('7') 宏使命列表记为:【s5 s6 s4 s789】
new Promise(function (resolve) {
setTimeout(function () {
console.log('8')
});
resolve()
}).then(function () {
setTimeout(function () {
console.log('9')
});
});
});
})
微使命实行终了了 该实行我们的宏使命列表了
由于微使命内里包括一部分宏使命
所以如今的宏使命列表已增加了
如今把当前的宏使命列表搬下来
//s5
setTimeout(function () { --------> 实行s5
console.log('5') 如今打印递次为:2、10、1、3、5
});
//s6
setTimeout(function () { --------> 实行s6
console.log('6') 如今打印递次为:2、10、1、3、5、6
});
//s4
setTimeout(function () { --------> 实行s4
console.log('4') 如今打印递次为:2、10、1、3、5、6、4
});
// s789
setTimeout(function () { --------> 实行s789
console.log('7') 如今打印递次为:2、10、1、3、5、6、4、7
new Promise(function (resolve) {
setTimeout(function () { --------> 被放宏使命列表
console.log('8') 宏使命列表记为:【s8】
});
resolve()
}).then(function () { --------> 团体的then被放微使命列表[包括内里的setTimeout]
setTimeout(function () { 微使命列表记为:【t9】
console.log('9')
});
});
});
再次小结:
当前效果:2、10、1、3、5、6、4、7
立时就要实行完了内心万分冲动啊 ( 浏览器的内心独白 ^▽^ ...)
宏使命列表以下:
// s8
setTimeout(function () {
console.log('8')
});
微使命列表以下:
// t9
then(function () {
setTimeout(function () {
console.log('9')
});
});
继承实行 照旧遵照有微则微 无微则宏
浏览器发明有一条微使命
那就最先实行吧~
//t9
then(function () {
setTimeout(function () { --------> 实行t9 把内里的setTimeout放入宏使命列表
console.log('9') 宏使命列表记为:【s8 s9】
});
});
微使命列表实行终了
最先实行宏使命(宏使命方才又有新增哦~[s9])
// s8
setTimeout(function () { --------> 实行s8
console.log('8') 如今打印递次为:2、10、1、3、5、6、4、7、8
});
// s9
setTimeout(function () { --------> 实行s9
console.log('9') 如今打印递次为:2、10、1、3、5、6、4、7、8、9
});
到这里 微使命列表 和 宏使命列表均为空 就实行终了了
再此留下一道没有答案的题供练手
new Promise(function (resolve) {
console.log('1');
resolve();
}).then(function () {
setTimeout(function () {
console.log('2')
});
});
setTimeout(function () {
console.log('3')
process.nextTick(function() {
console.log('4');
})
process.nextTick(function() {
console.log('5');
})
});
new Promise(function (resolve) {
console.log('6');
resolve();
setTimeout(function () {
console.log('7')
new Promise(function (resolve) {
console.log('8');
resolve();
}).then(function () {
setTimeout(function () {
console.log('9')
});
});
});
}).then(function () {
setTimeout(function () {
console.log('10')
});
new Promise(function (resolve) {
console.log('11');
resolve();
}).then(function () {
setTimeout(function () {
console.log('12')
});
});
});
本人学问有限 文章多有不足
如有毛病 请慷慨指出 以避免误导别人