简述JavaScript中 同步与异步,阻塞与非阻塞

很多开发者都说JavaScript是单线程的,但是单线程是如何实现异步的呢?然而并没有详细说过,其实JavaScript还有一条或者多条线程用来实现异步操作,也就是异步队列。

  举个例子:

    马路上有很多车,一辆接一辆的排着跑,突然排在最前面的车坏了,

    这时候你是让后面的所有的车都等它修好在一起跑吗?

    然而是不可能的,那样交通就乱掉了。

    这时候就出现了应急车道,把坏的车挪到应急车道上去,

    后面的车继续跑,等坏的车修好了,在挪到车道上去正常跑。

    这就是JavaScript中的异步执行队列。

      什么是同步什么是异步呢?

    同步

    简而言之,同步就是从上往下依次执行,就像java,c,python等强类型的语言。都是顺时同步执行,很少有异步操作。

    而同步就要求开发者的编码要严谨,如果有疏忽,就会导致运行出错,运行卡顿,导致用户体验差等,

    举个简单的例子说明什么是同步执行

      // f1函数
      function f1() {
      console.log('f1', 1)
    }

    // f2函数

    function f2 () {
      console.log('f2', 2)
    }
    f1() // f1,1
    f2() // f2, 2

    这就是同步执行, f1() 在f2()的上面所以先执行 f1() 在执行f2() 简单说就是一个先进先出的队列。后者必须等待前者的结果出来才会运行

    那么如果我不想让f2等着f1执行完在执行,我就想让他正常执行呢? 那你就用异步函数编程就行 我推荐大家看一下阮一峰老师的异步函数式编程(http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html

    ),当然面试的时候不推荐拿出来吹牛逼。

    异步

    那么就把f2当成f1的参数,把f2写成f1的回调函数,这样f2不用再等待f1是否执行完成,只要过了1s就会执行f2函数

    function f1 (callback) {

      setTimeOut (() => {

        callBack()

      }, 1000)

    }

    f1(f2)

             阻塞

    什么是阻塞?

    阻塞与非阻塞其实跟同步与异步并没有什么直接关系。要正确理解。不要说阻塞=同步,非阻塞=异步

    最常见的阻塞现象,例如  死循环, 用户体验差, 运行卡顿等。引起阻塞的原因,就是一个api或者函数运行时,独占cpu导致其他代码无法运行。

             为什么大家会把阻塞与同步联系在一起了?

      开发者都知道同步代码从上至下依次运行,当运行遭遇阻塞,后面的代码自然而然不会运行。

            非阻塞呢?

    一说到非阻塞大家应该会想到   node, 因为nodejs最大的优点就是他的 异步非阻塞IOnode中大部分都是异步的,包括基于node开发的express,koa等框架。

    node进程中,一个用户线程(js单线程),一个异步线程池(用户无法直接访问到),对于真正的阻塞代码,比如异步中发生阻塞,如果跑在异步中的仍然是阻塞代码,那么这种异步根本起步到解决阻塞的作用,因为阻塞代码会独占cpu,多以导致本进程上面的所有代码都要等待,不管是哪个线程,但是node的IO是不会霸占cpu的,所以node最出色的就是他的异步非阻塞IO。真正碰到阻塞代码,node也只能开多线程多服务来解决了,因为每一门语言必然有他的优点与缺点,node本身就是为了让开发者更好的开发web后台服务的。

    同步异步,阻塞与非阻塞就说到这里了。

原文地址:https://www.cnblogs.com/0915ty/p/9776945.html