zoukankan      html  css  js  c++  java
  • js同步和异步

    同步和异步

    异步并不是同步,异步是单线程,异步指的是让CPU暂时搁置当前请求的响应,处理下一个请求,当通过轮询或其他方式得到回调通知后,开始运行。

    并发是多线程,

     同步:一定要等任务执行完了,得到结果,才执行下一个任务。
     异步:不等任务执行完,直接执行下一个任务。

    简而言之,言而总之:同步就是我强依赖你(对方),我必须等到你的回复,才能做出下一步响应。即我的操作(行程)是顺序执行的,中间少了哪一步都不可以,或者说中间哪一步出错都不可以,类似于编程中程序被解释器顺序执行一样;同时如果我没有收到你的回复,我就一直处于等待、也就是阻塞的状态。 异步则相反,我并不强依赖你,我对你响应的时间也不敏感,无论你返回还是不返回,我都能继续运行;你响应并返回了,我就继续做之前的事情,你没有响应,我就做其他的事情。也就是说我不存在等待对方的概念,我就是非阻塞的。

    我们先不深入异步概念,先从「表象」来看看怎么样的代码是异步代码:

    异步代码的书写顺序与执行顺序不同。

    区别: 会不会阻塞当前程序运行

    什么时候需要异步:

    (1)需要等待的时候,等待过程不能卡在这吧

    (2)等待过程不像alert一样阻塞程序运行

    (3)等待的情况都要异步

    使用异步的场景:

    (1)定时任务,setTimeout,setInterval

    (2)网络请求: ajax请求,动态<img>加载

    (3)事件绑定,点击等交互事件

    几个问题:

    1. 同步和异步的区别是什么

       同步阻塞代码运行,alert是同步,setTimeout是异步

    2. 一个setTimeout的例子

    JS引擎扫描一遍,将事件按顺序加入任务队列,然后执行,此时注意setTimeout中的函数是在定时完成后才会加入队列

    所以刚开始队列中 有 console.log(1),setTimeout(fn1,0),console.log(3),setTimeout(fn2,1000),console.log(5)

    输出1,执行setTimeout后,再过0ms将fn1加入到任务队列尾部,此时队列中有console.log(3),setTimeout(fn2,1000),console.log(5),fn1

    再输出3,执行setTimeout,过了1000ms将fn2加到任务队列尾部,输出5,再执行fn1,fn2

    事件执行过程中的事件循环,JS引擎有个运行栈,不断从任务队列里读取任务运行,运行栈为空,便检查任务队列,一直加入,循环往复,直至任务队列也为空

    什么情况下需要用到异步?

    现在有三个函数,taskA()、taskB() 和 taskC(),三个任务互不影响

    taskA 和 taskC 执行得很快,但是 taskB 执行需要 10 秒钟。

    // 同步的写法
    function taskB(){
      var response = $.ajax({
        url:"/data.json",
        async: false // 注意这里 async 为 false,表示是同步
      })
      return response // 十秒钟后,返回 response
    }
     
    taskA()
    taskB()
    taskC()

    taskC 一定要等 taskB 执行完了才能执行,这就是同步。

    执行顺序为:

    A -> B -> AJAX 请求 -> C ---------------------------
    

    现在换成异步:

    // 异步的写法
    function taskB(){
      var result = $.ajax({
        url:"/data.json",
        async: true // 异步
      })
      return result // 一定要注意,现在的 result 不是上面的 response
    }
    taskA()
    taskB()
    taskC()

    这样写之后,执行顺序就是

    1.  
      A -> B -> C ---------------------------------------
    2.  
      -> AJAX 请求 --------------------------------

    就是说 AJAX 请求和任务C 同时执行。

    但是请注意执行的主体。AJAX 请求是由浏览器的网络请求模块执行的,taskC 是由 JS 引擎执行的。

    综上,如果几个任务互相独立,其中一个执行时间较长,那么一般就用异步地方式做这件事。

    所以像setTimeOut定时任务、ajax请求都是需要一定的时间的,所以一般都是用异步方式,不会阻塞后边代码的执行,而是设置了定时时间之后、或发送了请求之后,就移动到单线程的任务队列的最尾端,等后边执行完之后再执行定时代码或者ajax请求的回调函数内代码。

    JS 引擎不能同时做两件事

    有些人说异步是同时做两件事,但其实 JS 引擎不会这样。

    以 setTimeout 为例,setTimeout 里面的代码一定会在当前环境中的任务执行完了「之后」才执行。

    异步意味着不等待任务结束,并没有强制要求两个任务「同时」进行。

    但是 AJAX 请求是可以与 JS 代码同时进行的,因为这个请求不是由 JS 引擎负责,而是由浏览器网络模块负责。

    以上,就是异步的简介。

  • 相关阅读:
    POJ1239
    HDU 2829 四边形不等式优化
    返回数字二进制的最高位位数o(n)
    矩阵快速幂 模板
    HDU4718 The LCIS on the Tree(LCT)
    HDU4010 Query on The Trees(LCT)
    HDU3487 Play With Chains(Splay)
    CF444C DZY Loves Colors
    HDU4836 The Query on the Tree(树状数组&&LCA)
    HDU4831&&4832&&4834
  • 原文地址:https://www.cnblogs.com/zhaoyanhaoBlog/p/11296223.html
Copyright © 2011-2022 走看看