> 文章列表 > [前端基础]异步操作(还没写完)

[前端基础]异步操作(还没写完)

[前端基础]异步操作(还没写完)

1.写在前面

这篇是因为最近再写异步操作,需要点总结

因为还在学习前端的过程中嘛,所以有些东西可能会慢慢补充上来,也可能会有很多个人理解不是很到位的地方,还望各位评论区佬能帮忙指出.阿里嘎多捏

2.异步操作的概念和举例

异步操作和同步操作在408的三门课程中,都有所提及,简单来说,异步操作是一种伪并行,它会将需要事件较长的事件暂时放到队列中,先执行所有的非异步操作.好像一个双线程的东西.

同步操作则是一根筋的处理方式,碰到一个时间较长的执行(比如上传文件)就卡死在这里了,不允许继续做什么.

具体的同步异步,其实和IO控制方式里面的,程序查询方式和程序中断方式很接近.

举个例子

for(var i=1;i<=3;i++){setIntervel(()=>{console.log(i);},1000)
}

猜猜这个执行结果是什么?每隔一秒钟分别输出1 2 3?

戳啦,输出结果是每隔三秒钟输出一个3

原因如下,每次遍历的时候,都有一个定时方法,这个东西会被js引擎当成异步来进行处理

而异步,会被挂到队列,年纪轻轻的引擎,就挂上了三个事件

在此期间,i逐渐自增,最终变成了3,因为变量提升的关系,我们可以在全局读到3,这个时候我们执行完了所有的同步内容,再开始处理队列内容,得到的结果是输出3;

(其他地方不理解记得去了解一下var的变量提升,另外如果想要免去这些操作的影响,可以使用立即执行函数来处理,立即执行函数会把内部的东西统统变成同步

3.关于异步操作的运行本质

要了解异步操作,首先就要了解js中的事件循环.除了常规的栈区和堆区,js引擎还附带了一个事件队列(event queue),用来临时存放异步操作.

比如说,我们运行了一个操作中,有同步,有异步,顺着往下执行,会先把所有的同步操作给执行完,然后在开始按照队列中的顺序执行异步

 每次碰到一个异步操作,就会将其放入事件队列中等待执行.js引擎会通过某些算法来维护这个队列的优先级

目前已知的优先级顺序

1.微操作>宏操作(前者全都执行完了,才轮到后者)

2.同类型的操作,会按照时间排序

4.最简单的异步操作处理机制:回调函数

首先说明:回调函数本身和异步没啥关系,其定义只是把函数当成一个参数传入进去而已

因为这个东西可以起到一个很好的视觉效果和理解能力,所以拿来当作处理异步最通俗的方式

例如,我们用这种方式来进行一个ajax请求

function fetchData(url) {console.log("调用回调函数1");   //1var ii=1;const xhr = new XMLHttpRequest();xhr.open('GET', url, true);xhr.send();console.log("已经发送过send异步方法了2");  //2xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {//因为这个请求铁定是失败的,所以我们不要抱有什么幻想了}else{console.log("快,输出点什么证明你还活着!5");// callback("第"+ ii++ +"次执行回调函数5");   //5}}console.log("先打印这个??3");     //3}fetchData('https://api.example.com/data', function(response) {console.log('请求成功,返回数据为:', response);});console.log("这个也是立即执行的东西4");   //4

猜猜这个东西的执行顺序是什么(你也可以自己跑一下)

 问题不大,很符合我们之前的预期

这里简单说一下原理,send函数是一个异步操作,当触发send的时候,会把后续的变化挂载到事件队列中(就是触发的readystate的改变,这一大段的内容都会挂载到事件中)

等待同步方法执行完了,队列中就会调出这个东西并且执行

下面是一个个人不太成熟的看法

回调函数其实可有可无,只不过这个形式有助于我们理解队列的挂在

这个回调函数可以把我们想要的内容给直接封装在内罢了