资讯专栏INFORMATION COLUMN

同步与异步、异步与回调

dinfer / 1117人阅读

摘要:同步与异步以上为同步代码,函数必须等函数执行完毕后才能执行。异步回调产生的结果就是,函数的调用并不直接返回结果,而往往是交给回调函数进行异步处理。

同步与异步:
    function a(){}
    function b(){}
    
    a();
    b();

以上为同步代码,函数b必须等函数a执行完毕后才能执行。

    function a(){
        setTimeout(function(){
            b();
        }, 1000);
    };
    function c(){};
    
    a();
    c();

首先执行函数a,而且不等setTimeout执行就执行函数c,等待至少1s的时候后才会执行函数b.实际上在是等待了1s后将函数b放到了event queue里面,此时要等待主线程空闲的时候,才会取event queue里面等待的回调函数进行执行。

以上是一段简单的异步代码,js里面最基础的异步实现就是调用setTimeout,setInterval

关于js的异步实现请看下面的list:
谈谈javascript的异步实现

回调:

回调函数:在js里面简单点来说,就是函数被当作参数传入另外一个函数当中,并在那个函数中被调用。

    
    var b = function (){
        //执行相关的代码
    }
    var a = function (b){
        //执行相关的代码
        b();
    }
    
    a(b);
异步与回调:

大家可能平时听的比较多的是异步回调,但是必须搞清楚,异步与回调并没有直接的联系,回调只是异步的一种实现方式。
当然还有同步回调,即上面回调部分举的简单的例子。一般使用回调函数主要是将父函数的执行结果通知给回调函数进行处理。

关于异步我的理解是:

因为js是单线程的,如果所有的操作(如ajax操作,获取远程的js文件等IO操作)是同步的,遇到那些耗时的操作,后面的程序必然被阻塞不能执行,页面也就失去了响应。因此js采用了事件驱动机制,在单线程模型下,使用异步回调函数的方式来实现非阻塞的IO操作

异步任务 是指js在主线程(stack)运行的过程当中,当stack空闲的时候,主线程对event queque轮询(事实上一直在轮询)后,将异步任务放到stack里面进行执行。简单点说,只要指定过回调函数,那么当这些事件发生的时候就会进入事件队列,等待主线程的stack空闲的时候,就会对event queue里面的回调读取并放到stack里面执行。

看一段ajax实现的代码:

    var xhr = new XMLHttpRequest();
    xhr.open("POST", url, true);   //第三个参数决定是否采用异步的方式
    xhr.send(data);
    xhr.onreadystatechange = function(){
        if(xhr.readystate === 4 && xhr.status === 200){
                ///xxxx
        }
    }

这里ajax请求是异步的,因为浏览器会新开一个线程请求,当请求的状态(readystate)发生改变,因为之前就设置了回调函数,每次状态发生改变都会调用相应的回调函数,当(xhr.readystate === 4 && xhr.status === 200)的时候,回调函数进入了event queue,等待主线程空闲的时候,并且event queue里面排在这个回调前面没有其他回调的时候就会得到执行。

异步回调产生的结果就是,函数的调用并不直接返回结果,而往往是交给回调函数进行异步处理。

因此在异步编程当中,需要注意几个地方:

需要把依赖于异步函数(需要其执行结果或者达到某种状态)的代码放在对应的回调函数中(例如上面的ajax的例子)

异步函数后面的代码会立即执行(因此需要知道某段代码是否为异步的)

另外还有一个关于script标签异步加载的内容:
大家记得请求远程脚本标签吗?

    

在script标签里面加入了async属性或者defer属性后,同样变成了异步了。
关于这部分的内容,请移步:
async和defer的区别

另外关于这部分的内容还有一些List:
并发模型与event loop
朴灵评阮老师的event loop

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/86138.html

相关文章

  • JS—异步回调、高阶函数

    摘要:而是在调用发出后,被调用者通过状态通知来通知调用者,或通过回调函数处理这个调用。请求程序发出请求,从服务器端获取数据,并设置了回调函数。然后,浏览器会设置侦听来自网络的响应,拿到数据后,将该回调函数插入到事件循环。 并发与并行 并发是指两个或多个事件链随时间发展交替执行,以至于从更高的层次来看,就像是同时运行(但在任意时刻只处理一个事件) 并发的关键是你有处理多个任务的能力,不一定同...

    Dean 评论0 收藏0
  • 异步

    摘要:在异步机制中,任务队列就是用来维护异步任务回调函数的队列。四对象对象是工作组提出的一种规范,目的是为异步编程提供统一接口。 异步 1.JavaScript单线程的理解 Javascript语言的执行环境是单线程(single thread)。所谓单线程,就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。 2.JavaScript单线...

    goji 评论0 收藏0
  • 浅析JavaScript异步

    摘要:回调函数,一般在同步情境下是最后执行的,而在异步情境下有可能不执行,因为事件没有被触发或者条件不满足。同步方式请求异步同步请求当请求开始发送时,浏览器事件线程通知主线程,让线程发送数据请求,主线程收到 一直以来都知道JavaScript是一门单线程语言,在笔试过程中不断的遇到一些输出结果的问题,考量的是对异步编程掌握情况。一般被问到异步的时候脑子里第一反应就是Ajax,setTimse...

    Tangpj 评论0 收藏0
  • JavaScript:彻底理解同步异步和事件循环(Event Loop)

    摘要:例如处理请求的线程处理事件的线程定时器线程读写文件的线程例如在中等等。事件循环事件循环是指主线程重复从消息队列中取消息执行的过程。事件触发时,表示异步任务完成,会将事件监听器函数封装成一条消息放到消息队列中,等待主线程执行。 一. 单线程 我们常说JavaScript是单线程的。 所谓单线程,是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个。不妨叫它主线程。 但是实...

    wenyiweb 评论0 收藏0
  • 总结:JavaScript异步、事件循环消息队列、微任务宏任务

    摘要:单线程异步非阻塞然后,这又牵扯到了事件循环消息队列,还有微任务宏任务这些。此步的位置不确定某个时刻后,定时器触发线程通知事件触发线程,事件触发线程将回调函数加入消息队列队尾,等待引擎线程执行。 前言 Philip Roberts 在演讲 great talk at JSConf on the event loop 中说:要是用一句话来形容 JavaScript,我可能会这样: Java...

    qianfeng 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<