贵阳58同城做网站公司有哪些,南京最专业app开发公司,网站建站平台,各类资源关键词我们在前后端交互的过程中#xff0c;通常是通过请求接口来实现的#xff0c;而一个页面中的交互又非常复杂#xff0c;例如需要多次频繁请求同一个接口#xff0c;或者在接口还没返回时就要切换路由等。这些都需要对接口请求的时机或者请求接口之后进行处理#xff0c;避…我们在前后端交互的过程中通常是通过请求接口来实现的而一个页面中的交互又非常复杂例如需要多次频繁请求同一个接口或者在接口还没返回时就要切换路由等。这些都需要对接口请求的时机或者请求接口之后进行处理避免一些无用的请求或者接口返回顺序的差异。防抖在用户快速地交互过程中只使用最后一次交互产生的数据然后再发起请求例如频繁的切换 tab或者快速输入数据等锁状态在上一个接口没有返回数据时交互状态一直处于 loading 的锁定状态直到数据正确返回或者超时等异常取消上一个请求在发起下一个请求前把之前的请求取消掉前两种方式是在发起请求前进行控制即控制发起请求的时机而当请求发出之后则不再控制而最终一种方式则是取消中断还在路上的请求然后再发起一个新的请求不用管发起的时机。这几种方式也要看业务的需要选择最适合的即可。我们在之前的如何实现 axios 的自定义适配器 adapter文章里略过了 axios 是如何主动取消当前请求的。今天我们就将一下在 axios 中如何取消之前发起的请求源码中又是怎样实现的。1. 主动取消之前发起的请求我们先来看下 axios 中取消请求的用法const CancelToken axios.CancelToken;// 返回两个字段{ token, cancel }
// token用于表示某个请求是一个Promise类型
// cancel是一个方法当被调用时则取消token注入的那个请求
const source CancelToken.source();axios.get(/user/12345, {cancelToken: source.token, // 将token注入到请求中}).catch(function (thrown) {// 判断是否是因主动取消导致的if (axios.isCancel(thrown)) {console.log(Request canceled, thrown.message);} else {// handle errorconsole.error(thrown);}});axios.post(/user/12345,{name: new name,},{cancelToken: source.token,}
);// 主动取消请求
// cancel方法会把注入的同一个token的请求方法一并取消掉
// 上面的get和post请求都会被取消掉
// cancel the request (the message parameter is optional)
source.cancel(Operation canceled by the user.);
从 demo 上来看用法很简单token 和 cancel 的关系对应上即可。官方例子中还有一种取消请求的方式这个我们放在后面讲更容易理解一些。2. 源码解析取消请求的方法在 https://github.com/axios/axios/tree/master/lib/cancel 的目录中3 个文件Cancel: Cancel 类message 和__CANCEL__属性用于标识取消的某个请求isCancel: 判断当前参数是否是 Cancel 的实例CancelToken: 主流程创建 Cancel 实例和取消的方法我们主要来看下 CancelToken 中的整个流程。2.1 source 方法source 作为取消请求的入口我们就先来看下 source 方法。// 创建token和cancel方法
CancelToken.source function source() {var cancel;// token为 CancelToken 的实例包含 promise 和 reason 两个属性// 同时把 executor 中的参数给到 cancel// 即CancelToken有一个回调函数而这个回调函数的参数也是一个函数// CancelToken怎么执行我们接着看var token new CancelToken(function executor(c) {cancel c;});return {token: token,cancel: cancel,};
};
2.2 CancelTokenCancelToken 用来取消请求但我理解起来思路非常的绕我们一点点来剖析function CancelToken(executor) {if (typeof executor ! function) {throw new TypeError(executor must be a function.);}// 创建一个Promise的实例// 当resolvePromise执行时this.promise变为fulfilled状态var resolvePromise;this.promise new Promise(function promiseExecutor(resolve) {resolvePromise resolve;});// new一个实例时会立即执行CancelToken的回调函数executor方法// executor的参数也是一个函数即上面的cancel就是当前的cancel函数体// 当executor的回调函数cancel执行时会给当前CancelToken创建一个reason属性这个属性是Cancel的实例// 并执行resolvePromise方法将reason实例穿进去执行后this.promise变为fulfilled状态var token this;executor(function cancel(message) {if (token.reason) {// Cancellation has already been requestedreturn;}token.reason new Cancel(message);resolvePromise(token.reason);});
}
也就是说会先创建一个 CancelToken 的实例 token同时将 CancelToken 中回调函数的参数给到了 cancel。当 cancel 执行时则 token 中的 promise 属性则会从 pending 状态变为 fulfilled 状态那么 promise 上挂载的then()方法也就可以继续执行了。2.3 adapter在调用 cancel 方法后请求中是怎么操作的呢我们看下adapter/xhr.js中的代码if (config.cancelToken) {// config.cancelToken就是上面创建的token// 当token.promise变为fulfilled状态后就可以执行后续的链式操作// Handle cancellationconfig.cancelToken.promise.then(function onCanceled(cancel) {if (!request) {return;}// 取消当前的请求request.abort();// 将Cancel的实例cancel给到rejectreject(cancel);// Clean up requestrequest null;});
}
当我们使用 axios 的 catch 捕获内部抛出的异常时就可以通过isCancel判断是否是因主动取消请求导致的异常axios.get(/user/12345, {cancelToken: source.token, // 将token注入到请求中}).catch(function (thrown) {// 判断是否是因主动取消导致的if (axios.isCancel(thrown)) {console.log(Request canceled, thrown.message);} else {// handle errorconsole.error(thrown);}});
现在再来看下 cancel 执行的整个流程就会清晰流畅很多。3. 取消请求的另一种方式我们在第 1 节还留着一个问题axios 取消请求还有另一种方式即直接使用 CancelToken 类。token: 我们在上面的 source()方法中就能看到传给 axios 参数的 token 就是 CancenToken 的实例这里直接使用new CancelToken()的返回值也是可以的cancel: source()中的 cancel 就是 CancelToken 的回调函数 executor 的回调函数const CancelToken axios.CancelToken;
let cancel;axios.get(/user/12345, {// CancelToken创建的cancelToken: new CancelToken(function executor(c) {// An executor function receives a cancel function as a parametercancel c;}),
});// cancel the request
cancel();
其实我们发现source()方法只是给我们额外又封装了一下简单的返回了 token 和 cancel但本质还是 CancelToken 中的东西。4. 总结在取消请求的过程中token 要和 cancel 方法保持对应关系即都在一个对象里若其他的请求也要取消时可以额外再生成一组 token 和 cancel。同时这里还用到了 Promise 的一个机制只有在当前 Promise 变更为 fulfilled 状态后才能执行后面的 then 等操作。更多文章欢迎查看我的博客蚊子的前端博客www.xiabingbao.com