目录
线程和进程是操作系统中的两个概念:
进程(process):计算机已经运行的程序,是操作系统管理程序的一种方式
线程(thread):操作系统能够运行运算调度的最小单位,通常情况下它被包含在进程中
通俗的说就是:
进程:可以认为,启动一个应用程序,就会默认启动一个进程(也可能是多个进程)
线程:每一个进程中,都会启动至少一个线程用来执行程序中的代码,这个线程被称之为主线程,所以也可以说进程是线程的容器
再用一个形象的例子解释:
操作系统是如何做到同时让多个进程(边听歌、边写代码、边查阅资料)同时工作呢?
JavaScript是单线程(可以开启workers)的
但是JavaScript的线程应该有自己的容器进程:浏览器或者Node
注 : workers 可以让js开启多线程
浏览器是多进程的 :
JavaScript的代码执行是在一个单独的线程中执行的 :
真正耗时的操作,实际上并不是由JavaScript线程在执行的 :
如果在执行JavaScript代码的过程中,有异步操作
比如中间插入了一个setTimeout的函数调用
这个函数被放到入调用栈中,执行会立即结束,并不会阻塞后续代码的执行
- let name = 'coder';
-
- function bar() {
- console.log('bar function');
- }
- // 交给浏览器的其他线程执行
- setTimeout(() => {
- console.log('setTimeout');
- }, 10000);
-
- function foo() {
- bar();
- }
-
- foo();
-
- <script>
- const btn = document.querySelector('button');
-
- // 1. 绑定点击事件
- btn.onclick = function () {
- console.log('btn click event');
- };
-
- console.log('Hello World');
-
- // 2. 定时器1
- setTimeout(() => {
- console.log('0s后的setTimeout');
- }, 0);
-
- console.log('-------------');1
-
- // 3. 定时器2
- setTimeout(() => {
- console.log('10s后的setTimeout');
- }, 10000);
-
- console.log('-------------');
- script>
事件循环中并非只维护着一个队列,事实上是有两个队列 :
宏任务队列(macrotask queue):ajax、setTimeout、setInterval、DOM监听、UI Rendering等
微任务队列(microtask queue):Promise的then回调、 Mutation Observer API ( 监听dom变化的 )、queueMicrotask ( 直接把回调函数加入到微任务队列中 ( ) => { } )等
两个队列的优先级 :
- console.log('script start'); // 1
-
- setTimeout(function () {
- console.log('setTimeout1'); // 8
- new Promise(function (resolve) {
- resolve();
- }).then(function () {
- new Promise(function (resolve) {
- resolve();
- }).then(function () {
- console.log('then4'); // 10
- });
- console.log('then2'); // 9
- });
- });
-
- new Promise(function (resolve) {
- console.log('promise1'); // 2
- resolve();
- }).then(function () {
- console.log('then1'); // 5
- });
-
- setTimeout(function () {
- console.log('setTimeout2'); // 11
- });
-
- console.log(2); // 3
-
- queueMicrotask(() => {
- console.log('queueMicrotask1'); // 6
- });
-
- new Promise(function (resolve) {
- resolve();
- }).then(function () {
- console.log('then3'); // 7
- });
-
- console.log('script end'); // 4
- console.log('script start');
-
- function requestData(url) {
- console.log('requestData');
- return new Promise((resolve) => {
- setTimeout(() => {
- console.log('setTimeout');
- resolve(url);
- }, 2000);
- });
- }
-
- function getData() {
- console.log('getData start');
- requestData('why').then((res) => {
- console.log('then1-res:', res);
- });
- console.log('getData end');
- }
-
- getData();
-
- console.log('script end');
- console.log('script start');
-
- function requestData(url) {
- console.log('requestData');
- return new Promise((resolve) => {
- setTimeout(() => {
- console.log('setTimeout');
- resolve(url);
- }, 2000);
- });
- }
-
- // 2.await/async
- async function getData() {
- console.log('getData start');
- // await下面的代码,相当于一同在then方法中,是一起的
- const res = await requestData('why');
- console.log('then1-res:', res);
- console.log('getData end');
- }
-
- getData();
-
- console.log('script end');
- async function async1() {
- console.log('async1 start');
- await async2();
- console.log('async1 end');
- }
-
- async function async2() {
- console.log('async2');
- }
-
- console.log('script start');
-
- setTimeout(function () {
- console.log('setTimeout');
- }, 0);
-
- async1();
-
- new Promise(function (resolve) {
- console.log('promise1');
- resolve();
- }).then(function () {
- console.log('promise2');
- });
-
- console.log('script end');