随着AJAX技术的诞生,前端正式进入了局部刷新和前后端分离的新时代,最初的服务请求技术是XHR,随着技术发展和ES6的诞生,jquery ajax,axios,fetch 等技术的产生让前端的异步请求更便捷.

当我们使用异步请求的时候可能会有中断请求的需要.

比如当我们第一次查询数据的时候没有输入查询条件导致查询很慢,于是我们第二次添加了查询调价重新查询很快结果返回并渲染到了页面,

这时第一次的请求还在进行中,无法停止

当我们正在看数据的时候第一次的请求返回了结果并重新渲染了页面,导致数据混乱

各种请求技术怎么又该怎么实现呢?下边来分别进行简述:

一、XHR

1.说明

AJAX 使用的 XMLHttpRequest 的对象与服务器通信.让我们通过下面显示的图像了解 AJAX 的流程或 AJAX 的工作原理。

2.调用和中断

const xhr = new XMLHttpRequest();
const method = 'GET';
const url = 'https://xxx';
xhr.open(method, url, true);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
// do something
}
}
xhr.send(); setTimeout(()=>{
xhr.abort()}
,1000)

jquery Ajax由于也是相同的

var ajaxGet = $.get(“https://xxx”,
  {id:1},
 function(data){undefined ….//一些操作 }
);
ajaxGet.abort();

二、axios

1.说明

众所周知xhr技术虽然实现了异步调用但是如果连续有序地调用多个请求就会出现回调地狱的尴尬场面.

ES6推出的async/await promise可以很好的解决这个问题.而axios就是基于promise对xhr进行的封装

核心代码如下(简单模拟非源码):

 1  function axios(config){
2 return new Promise((resolve) => {
3 const {url='',data={},method='get'} = config; //解构传参
4 const xhr = new XMLHttpRequest; //创建请求对象
5 xhr.open(method,url,true);
6 xhr.onreadystatechange = () => {
7 if(xhr.readyState == 4 && xhr.status == 200){
8 resolve(xhr.responseText);
9 //异步请求返回后将Promise转为成功态并将结果导出
10 }
11 }
12 xhr.onerror = (err) => {
13 reject(err);
14 };
15 xhr.send(JSON.stringfy(data));
16 })
17 }

2.使用

 // then catch 链式调用
axios.get('/user')
.then(function (response) {
console.log(response);
axios.get('class?info=' + response.data.name);
})
.catch(function (error) {
console.log(error);
}); // async await
var info = await axios.get('user');
var ret = await axios.get('class?info=' + info.data.name);

3.中断(取消)

axios 的中断取消是基于 cancelable promises proposal

原理是内部生成一个Promise 将 resove 方法抛给外部的 source的cancel方法,

当外部调用这个方法时,内部的promise.then就会调用xhr.abort() 并调用外部的reject

可以使用 CancelToken.source 工厂方法创建 cancel token,像这样:

const CancelToken = axios.CancelToken;
const source = CancelToken.source(); axios.get('/user/12345', {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
   // 取消处理
console.log('Request canceled', thrown.message);
} else {
// 处理错误
}
}); axios.post('/user/12345', {
name: 'new name'
}, {
cancelToken: source.token
}) // 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');

还可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token:

const CancelToken = axios.CancelToken;
let cancel; axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// executor 函数接收一个 cancel 函数作为参数
cancel = c;
})
}); // cancel the request
cancel();

三、Fetch

1.说明

Fetch也是基于ES6 Promise 实现的一个服务器请求技术,但不是对xhr的封装.

也是底层的实现不需要引入包,是 XMLHttpRequest 的升级版.兼容除了IE的大部分浏览器

2.基本使用

 // then  catch 链式调用
fetch('https://xxxx')
.then(response => response.json())
.then(json => console.log(json))
.catch(err => console.log('Request Failed', err));

// async await
async function getJSON() {
let url = 'https:XXXX';
try {
let response = await fetch(url);
return await response.json();
} catch (error) {
console.log('Request Failed', error);
}
}

3.中断

Fetch的中断是基于webApi的 AbortController(实验阶段的功能兼容除了IE的大部分浏览器)

var controller = new AbortController();
var signal = controller.signal; // 可以监听取消事件
signal.addEventListener('abort',
() => console.log('abort!')
); setTimeout(()=>{
//定时或者手动调用abort方法中断
controller.abort();
},1000) fetch('http://xxxx', {signal}).then(function(response) {
...
}).catch(function(e) {
if(signal.aborted){
// 可以通过 signal.aborted 属性判断
...
}
if(e.name=='AbortError'){
// 也可以通过 error.name 判断
...
}
})/

四 、其他实现方法

其实在知道这些中断方法之前本人还用过其他的方法——uuid

主要思路就是每次调用请求的时候生成一个uuid,将这个uuid赋值给全局的变量同时作为参数传给请求的方法.

在请求返回处理数据的时候验证当前的全局uuid 是否和当前调用参数是否一致,不一致就不渲染数据,

这样就能保证渲染的数据是最后一次调用请求的数据

//以Fetch为例

this.uuid = ""

 // 自己写一个生成uuid的方法,或者使用第三方的包
function genUUID(){
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (Math.random() * 16) | 0
var v = c === 'x' ? r : (r & 0x3) | 0x8
return v.toString(16)
})
} function fetchData(){
// 赋值给局部变量和全局变量
let uuid = genUUID()
this.uuid = uuid
fetch(url).then(res=>{
if(this.uuid === uuid){
// 渲染数据
}
}) }

参考链接:
https://www.w3cschool.cn/ajax/ajax-tutorial.html
https://www.cnblogs.com/ysk123/p/11544211.html

异步请求与中断 ( XHR,Axios,Fetch对比 )的更多相关文章

  1. js循环调用axios异步请求,实现同步

    准备: const axios = require('axios'); // axios请求 const res = []; const arr = ["a", "b&q ...

  2. 前端总结·基础篇·JS(四)异步请求及跨域方案

    前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·JS(一)原型.原型链.构造函数和字符串(String) 前 ...

  3. vue-d2admin-axios异步请求登录,先对比一下Jquery ajax, Axios, Fetch区别

    先说一下对比吧 Jquery ajax, Axios, Fetch区别之我见 引言 前端技术真是一个发展飞快的领域,我三年前入职的时候只有原生XHR和Jquery ajax,我们还曾被JQuery 1 ...

  4. 异步请求xhr、ajax、axios与fetch的区别比较

    目录 1. XMLHttpRequest对象 2. jQuery ajax 3. axios 4. fetch 参考 why: 为什么会出现不同的方法呢? what: 这些都是异步请求数据的方法.在不 ...

  5. axios & fetch 异步请求

    // 一.创建实例 const request = axios.create({ baseURL: "http://kg.zhaodashen.cn/v2", headers: { ...

  6. ajax、axios、fetch 对比

    前言 今天在看到一个比较好的插件,写一个示例时,由于需要请求在线数据,官方给的是用 $.get(),就为了一个示例使用 JQuery 没必要. 又找了找,发现有用 fecth 的,挺方便,这里就做一个 ...

  7. axios浏览器异步请求方法封装 XMLHttpRequest

    axios学习笔记defaults(浏览器端异步请求处理方式) 浏览器异步请求方法封装,主要使用XMLHttpRequest lib/adapters/xhr.js //入口 var utils = ...

  8. Ajax_02之XHR发起异步请求

    1.Ajax: AJAX:Asynchronous Javascript And Xml,异步的JS和XML: 同步请求:地址栏输入URL.链接跳转.表单提交-- 异步请求:使用Ajax发起,底层使用 ...

  9. vue 中使用 async/await 将 axios 异步请求同步化处理

    1. axios 常规用法: export default { name: 'Historys', data() { return { totalData: 0, tableData: [] } }, ...

随机推荐

  1. 关于Oracle数据库的PIVOT分组函数的使用

    官方文档挺详细的,在新功能那里有介绍到:http://www.oracle-developer.net/display.php?id=506 PIVOT的语法:https://docs.oracle. ...

  2. 如何确保消息正确地发送至 RabbitMQ?如何确保消息接收方消费了消息?

    发送方确认模式 将信道设置成 confirm 模式(发送方确认模式),则所有在信道上发布的消息都会被指派一个唯一的 ID.一旦消息被投递到目的队列后,或者消息被写入磁盘后(可持久化的消息),信道会发送 ...

  3. 为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动 的区别在哪里?

    Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联 集合对象时,可以根据对象关系模型直接获取,所以它是全自动的.而 Mybatis 在查询关联对象或关联集 ...

  4. Redis String Type

    Redis字符串的操作命令和对应的api如下: set [key] [value] JedisAPI:public String set(final String key, final String ...

  5. C++ - C语言中数组的另一种常用写法(数组大小可变!!!)

    在 C 和 C++ 中,数组在声明过程中,数组名称为 const 指针,不许修改.且数组的大小在声明时被写死,非常不方便. C语言中常用下面代码替代指针. #include <stdio.h&g ...

  6. Matlab解析LQR与MPC的关系

    mathworks社区中的这个资料还是值得一说的. 1 openExample('mpc/mpccustomqp') 我们从几个角度来解析两者关系,简单的说就是MPC是带了约束的LQR. 在陈虹模型预 ...

  7. Cloud Design Patterns & Architecture Styles

    Cloud Design Patterns Categories Data Management Design and Implementation Messaging Patterns Ambass ...

  8. Nuxt.js服务端渲染实践,从开发到部署

    感悟 经过几个周六周日的尝试,终于解决了服务端渲染中的常见问题,当SEO不在是问题的时候,或许才是我们搞前端的真正的春天,其中也遇到了一些小坑,Nuxt.js官方还是很给力的,提issue后很积极的给 ...

  9. webSocket原理探索

    本文概述 Web Sockets的目标是在一个单独的持久连接上提供全双工.双向通信.在Javascript创建了Web Socket之后,会有一个HTTP请求发送到浏览器以发起连接.在取得服务器响应后 ...

  10. JavaScript 中 append()、prepend()、after()、before() 的区别

    内容 append().prepend().after().before() 的区别 jQuery 操作 DOM 之添加节点 方法名 作用 $(selector).append() 指定元素内部添加, ...