嚼一嚼event loop

js设想为单线程

js设想为单线程照样跟他的用处有关

试想一下 假如js设想为多线程 那末同时修正和删除同一个dom 浏览器又该怎样实行?

《嚼一嚼event loop》

js须要异步

for (var i=0;i<9999;i++){
  console.log("我在实行 但用户不知道")
}
console.log("你好啊")

上图例子 for轮回耗时会良久

这意味着 用户得不到 ‘你好啊’ 的相应 就会下意识会以为浏览器卡死了 所以js必需要有异步

js经由过程事宜轮回来完成异步 这也是js的运行机制

一方面代码逐步跑着 另一方面用户已抓狂

《嚼一嚼event loop》

js事宜轮回 (说白了不停实行俩步骤)

一、归类

碰到同步使命直接实行,碰到异步使命分类为
宏使命(macro-task)
微使命(micro-task)

宏使命:团体的
Script
setTimeout
setInterval

微使命:
Promise
process.nextTick

《嚼一嚼event loop》

请看示例代码:

// 这是一个同步使命
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')
      });
    });
  });

本人学问有限 文章多有不足

如有毛病 请慷慨指出 以避免误导别人

    原文作者:cchao
    原文地址: https://segmentfault.com/a/1190000019038936
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞