1.简单的解决方式,通过给请求编号,然后计数,最后的计数位是否与请求编号相同,否则return结果(比较是否是最后一个请求).
但是这样简单的方法在实际使用中并不方便,你总是需要想办法返回一个计数,然后做比较判断,每个请求还都要重写一遍。
2.结合了 Promise 和 XHR.abort()
XMLHttpRequest 提供的 abort 方法 可以用来将 XMLHttpRequest 的 readyState 置为 0。这样就可以视为请求被 “终止” 了 。
只是前端视角上的"终止",实际上请求还是会到达服务器的。
新建一个app.js node服务器进行模拟
请求按顺序发出了,但是响应是不定时的。
解决方法:
在连续的请求过程中,每当我发出一个请求,我就将之前正在 pending 的请求的 Promise reject 掉,并且该请求的 XHR
对象执行 abort() 之前的请求 如果已经有响应的不用管它,我们当前的请求的结果会覆盖它的
那么问题来了,怎样才能记录之前的请求,还要能在适当的时机执行对它的一系列操作呢? 这个问题,其实 Promise
自己就是答案。仔细想一想,只要 Promise 的状态改变了,就会在 .then 或者 .catch
中执行我们之前写好的回调函数,而且利用这个回调函数,刚好可以用来保存之前的请求。简直完美 这样的话,就需要我们自己生成一个 Promise
并把它的 .then 回调关联到我们的 xhrAdapter 中,回调函数中会保存当时的 XHR 请求对象和其包装 Promise
的reject 方法,有了这两个对象就可以达到我们的目的了。 那下面我们就来具体实现一下这个想法 首先,总不能每次都写一遍生成
Promise 的代码。这里就构造一个名为 CancelToken 的类用来生成
Promise,为了防止多次执行取消操作,也对取消请求操作进行记录, 需要同样的构造一个 Cancel 的类
这样的话其实也有一个小问题,就是这个两个类和具体发出请求的方法,也就是 handleInput 肯定是不在一起的了,那如何才能在外(handleInput 中)控制一个 Promise 的状态呢?
上面的实现就是 Axios 的源码的简陋版本
3.fetch 和 AbortController
然而并不是所有的请求都是使用 XHR 的,使用 fetch 的并不少见。用了 fetch 的,可以使用 AbortController 来阻止请求。