前端数据获取之Ajax与Fetch (一)

Ajax,读作”阿贾克斯“,这个是每一个web开发者必掌握的一门技术,现在咱们打开一个网页,页面上数据多多少少都会有它的一些参与,来获取数据,但也并不是所有的数据都是通过它来取到的。

Ajax是Asynchronous JavaScript and XML的缩写,中文意思异步的Javascript和XML。

何为异步?

对比同步来说,javascript本身是占用一个线程执行的,如果要以同步的方式发起请求,那就是让这个线程阻塞,等待这个网络请求发出去,然后请求回来,javascript才能接着执行。你可以想象这个的过程,javascript的执行线程一直被占用着,网络请求回来之前,用户只要涉及到javascript脚本操作势必没有任何响应。再解释异步方式,可以理解为javascript发起网络请求时只是立了一个flag,浏览器让其他线程去发了请求,javascript线程继续干自己的事情,等其他线程请求完成回来后,再给javascript立的flag打一个call,javascript线程接到通知继续执行。异步的这种方式能够及时放开javascript脚本执行线程,在页面上,用户多次点击发起请求或者脚本操作都不会受到影响,是比较理想的。宏观上只要记住异步javascript就是不影响当前页面动作的一段javascript代码,这段代码会立flag,并且有一一个回调函数会在将来某个时刻执行。

认识XML

XML,可扩展标记语,是一种语言格式。很多人熟悉JSON格式,你可以做用它和XML类比。XML也有自己的规范,和HTML很像,两个标签中间携带数据。为什么要用它来数据传输呢?我觉得可以理解为不同界域直接的解耦,它是跨平台,跨操作系统,跨语言的一种数据传输的统一标准实现。只不过现在的前端都习惯更方便直观的JSON格式作为数据传输,而告别XML了,现在很少见XML的返回格式了,AJAX应该改名为AJAJ比较合适。

AJAX实现原理

本质是浏览器底层与操作系统暴露出来的一个API,在浏览器中有一个XMLHttpRequest的构造函数,当我们用一些包如jQuery的ajax或者Axiso请求数据时,用的其实就是它的实例。

XMLHttpRequest是浏览器提供了事件通知机制引擎是所暴露出来的API,当发起请求立flag的时候,就是告诉底层,我订阅了这个消息,你要在请求回来的时候通知我,它会暴露出一些钩子给你,你便可以传相应的处理函数进去,等它触发事件,钩子函数得到执行,你传入的回调也得到执行。

AJAX的兼容性

它在一般我们常用的浏览器中是这样实现的。

new window.XMLHttpRequest();

但是有一部分IE中没有XMLHttpRequest,提供了另一个API做相同的事情。

new window.ActiveXObject(Microsoft.XMLHTTP);

AJAX的实现

AJAX的简单实现,只为了解原理去实现,不考虑细节了,大家可以翻jQuery的ajax去看完整源码。

function Ajax() {
    const xhr = new XMLHttpRequest();
    console.log('readyState0:', xhr.readyState);
    xhr.open('GET', 'https://juejin.im/post/5cf0733de51d4510803c22e34es', true);
    console.log('readyState1:', xhr.readyState);
    xhr.onreadystatechange = function(res){
      console.log('readyState:', xhr.readyState);
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          console.log('请求成功');
        } else {
          console.error('请求异常, response code:', xhr.status)
        }
      }
    }
    xhr.send();
}

Ajax();
执行结果:
readyState0: 0
readyState1: 1
readyState: 2
readyState: 3
readyState: 4
VM请求异常, response code: 404

在上面搜了一个不存在的掘金文章编号,返回值404了。大家也可以打开掘金https://juejin.im 打开控制台调试看一下。

解释一下里面的关键点,当new XMLHttpRequest实例后。这个实例有5种状态,可以在它里面readyState 的属性获取到当前状态。

当实例化成功时,readyState为0,实例执行open方法,readyState为1,这两个均为同步操作内容,请求尚未发送。

当实例的send方法执行后,请求发送。readyState的变化均可以在onreadystatechange中捕获到。

发送的请求被接受后,xhr引擎触发onreadystatechange,readyState为2;发送的请求被处理,xhr引擎触发onreadystatechange,readyState为3;发送的请求处理完成返回,xhr引擎触发onreadystatechange,readyState为4。

可以清晰的看到onreadystatechange一共触发了3次,但是需要的数据内容只有在readyState为4时才会存在,所以我们只需要将readyState=4的内容返回处理即可,xhr的status代表可服务器返回的请求的转态码,当200时说明请求正常,其余情况均属于异常情况,上面代码即为404情况。

上面的代码在执行open方法的时候传入了true,这代表本次请求是异步的,下面看一下同步的情况。

function Ajax() {
    const xhr = new XMLHttpRequest();
    console.log('readyState0:', xhr.readyState);
    xhr.open('GET', 'https://juejin.im/post/5cf3578af265da1ba431d656', false);
    console.log('readyState1:', xhr.readyState);
    xhr.onreadystatechange = function(res){
      console.log('readyState:', xhr.readyState);      
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          console.log('请求成功');
        } else {
          console.error('请求异常, response code:', xhr.status)
        }
      }
    }
    xhr.send();
    console.log('异步测试');
}

Ajax();
返回值:
readyState0: 0
readyState1: 1
readyState: 4
请求成功
异步测试

这时候我们看到跟一步不一样的onreadystatechange只被触发了一次,而且readyState的值也只有3中,且console.log('异步测试');这段代码在整个请求完成后才被得到执行,可见同步已将js执行阻塞。

AJAX的内容,本期先介绍这么多,下一期介绍一下ES6后新的数据请求方式Fetch。

如上内容均为自己总结,难免会有错误或者认识偏差,如有问题,希望大家留言指正,以免误人。

原文发布于微信公众号 - 全栈者(fullStackEngineer)

原文发表时间:2019-06-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券