JavaScript----单线程以及同步异步理解

JS为什么单线程同步异步理解


JavaScript语言的一大特点就是单线程,也就是说,同一时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?

  • JavaScript是单线程与他的用途有关。作为浏览器脚本语言,JavaScript的主要用途就是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个删除了这个节点,这时浏览器应该以哪个线程为准?。
  • 所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经称为了这门语言的特征,将来也不会改变。
  • 为了利用多核CPU的计算能力,HTML5提出了Web Worker标准,允许JavaScript创建多个线程,但是子线程完全受主线程控制,且不得操作DOM,所以这个标准并没有改变JavaScript单线程的本质。

同步和异步

  • 单线程意味着,所有队伍都需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时过长,后一个任务就不得不一直等着。于是,就有了一个概念,任务队列。
  • 例如 进行网络请求时,网速不行,需要很长事件才能得到结果,比如20秒才能得到结果,这是CPU是空闲的,此时任务队列不得不等待结果出来,再往下执行。
  • JavaScript设计者意识到。这是主线程可以完全不管IO设备,挂起等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,在回过头,把挂起的任务继续执行下去。
  • 于是,所有的任务都可以分为两种。同步(synchronous)和异步(asynchronous)。
  • 同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行下一个任务。
  • 异步任务:不进入主线程,而进入”任务队列”(task queue)的任务只有”任务队列”通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
  • 对于异步操作,阮一峰大哥的解释颇为明朗
    所谓 “异步”,就是一个任务不是连续完成的,可以理解为被人为分成两段,先执行第一段,然后转而去执行其他任务,等做好了准备,在回过头来执行第二段。
    比如,有一个任务是读取文件进行处理,任务的第一段是向操作系统发出请求,要求读取文件。然后,程序执行其他惹他任务,等到操作系统返回文件,再接着执行任务的第二段(处理文件)。这种不连续的执行,就叫做异步。
  • 相应地,连续的执行就叫做同步。由于是连续执行,不能插入其他任务,所以操作系统从硬盘读取文件的这段时间,程序只能干等着

回调函数(callback)

JavaScript对异步编程的实现,就是回调函数,就是把任务的第二段,单独写在一个函数里面,等到重新执行这个任务的时候就直接调用这个函数。回调函数的英文名callback ,直译过来就是”重新调用”。
例如 :读取文件,然后处理文件

    fs.readFile('/et/passwd','utf-8',function(err,data){
        if (err) throw err;
        console.log(data);
    }

这个例子中,readFile的第三个参数,就是回调函数,也就是任务的第二段,等到系统返回了/et/passwd’这个文件以后,回调函数才会执行。
+ Promise是异步编程的一种解决方案。能够帮助理解异步。

猜你喜欢

转载自blog.csdn.net/yufanhui/article/details/82632376