js为啥是设计成单线程而不是多线程呢

了解这个问题之前,需要先了解一下以下问题:

  • 什么是进程?什么是线程?二者有啥关联?
  • 任务队列是什么?宏任务?微任务?eventloop?
  • 为什么说js是单线程,为什么要设计成单线程?
一,什么是进程?什么是线程?二者有啥关联?

        进程:CPU资源分配的最小单位;浏览器是多进程的,每个tab页都是一个进程;

        线程:CPU调度的最小单位;一个进程中可以有多个线程;

        举例:进程就是一个公司,每个公司都有自己的资源进行调度,公司之间是相互独立的;而线程就是公司的每个员工,多人协作完成任务,员工之间共享公司的空间;

二,事件循环,宏任务、微任务

        所有的任务都可以分为同步任务、异步任务;同步任务,就是立即执行的任务,一般会进入主线程中执行;异步任务,比如promise、ajax网络请求、setTimeout函数等都属于异步任务,会通过任务队列的先进先出的原则来进行协调;

        事件循环(Event Loop):主线程内的任务执行完之后,会去任务队列读取任务推入主线程,以此循环,直到任务全部执行完成。

        异步任务分类:宏任务(macro-task)、微任务(micro-task);

js为啥是设计成单线程而不是多线程呢_第1张图片

        那宏任务、微任务的执行顺序,就是如果微任务里面有任务的话,就先把微任务执行完再去执行下一个宏任务;

        宏任务主要包括:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境);

        微任务主要包括:Promise、MutaionObserver、process.nextTick(Node.js 环境);

演示代码如下:

// 这是一个同步任务
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、4、2、5

三、为什么说js是单线程,为什么要设计成单线程?

        js设计为单线程是跟它的用途有关,因为js作为浏览器的脚本语言,主要就是实现用户与浏览器的交互以及操作DOM,这就决定了js只能是单线程,要不然就会带来很复杂的同步问题,比如:假如js是多线程,如果一个线程要修改某个DOM,而另外一个线程要删除这个DOM,此时浏览器就不知道该如何操作了,一脸茫然;所以为了避免复杂性,从诞生开始就是单线程。

你可能感兴趣的:(web前端,javascript,开发语言,javascript,前端)