必备:如何中断已发出去的请求?

41 篇文章 0 订阅
17 篇文章 0 订阅

面试官:请求已经发出去了,如何取消掉这个已经发出去的请求?

面试者:(脑海里立马产生一个疑惑:已经发出去的请求还能取消掉?) 这个…这个…还真不知道。

面试完,马上找度娘…

推荐阅读:axios解析之cancelToken取消请求原理[2]

AbortController

AbortController[3] 接口表示一个控制器对象,可以根据需要终止一个或多个Web请求。

  • AbortController():AbortController()构造函数创建一个新的 AbortController 对象实例

  • signal:signal 属性返回一个 AbortSignal 对象实例,它可以用来 with/about 一个Web(网络)请求

  • abort():终止一个尚未完成的Web(网络)请求,它能够终止 fetch 请求,任何响应Body的消费者和流

Fetch 中断请求

Fetch 是 Web 提供的一个用于获取资源的接口,如果要终止 fetch 请求,则可以使用 Web 提供的 AbortController 接口。

首先我们使用 AbortController() 构造函数创建一个控制器,然后使用 AbortController.signal 属性获取其关联 AbortSignal 对象的引用。当一个 fetch request 初始化时,我们把 AbortSignal 作为一个选项传递到请求对象 (如下:{signal}) 。这将信号和控制器与获取请求相关联,然后允许我们通过调用 AbortController.abort() 中止请求。

const controller = new AbortController();
let signal = controller.signal;
 console.log('signal 的初始状态: ', signal);

const downloadBtn = document.querySelector('.download');
const abortBtn = document.querySelector('.abort');

downloadBtn.addEventListener('click', fetchVideo);

abortBtn.addEventListener('click', function() {
  controller.abort();
 console.log('signal 的中止状态: ', signal);
});

function fetchVideo() {
  //...
  fetch(url, {signal}).then(function(response) {
    //...
  }).catch(function(e) {
    reports.textContent = 'Download error: ' + e.message;
  })
}

当我们中止请求后,网络请求变成了如下所示的情况:

我们再来看看 AbortSignal 中止前和中止后的状态:

可以看到,AbortSignal 对象的 aborted 属性由初始时的 false 变成了中止后的 true 。

线上运行示例[4] (代码来源于MDN[5])

AbortControllter 有兼容性问题,如下:

axios 中断请求

axions 中断请求有两种方式:

方式一

使用 CancelToken.souce 工厂方法创建一个 cancel token,代码如下:

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('https://mdn.github.io/dom-examples/abort-api/sintel.mp4', {
  cancelToken: source.token
}).catch(function (thrown) {
  // 判断请求是否已中止
  if (axios.isCancel(thrown)) {
    // 参数 thrown 是自定义的信息
    console.log('Request canceled', thrown.message);
  } else {
    // 处理错误
  }
});

// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');

中止后的网络请求变成如下所示:

我们再来看看初始时和中止后的 souce 状态:

可以看到,初始时和中止后的 source 状态并没还有发生改变。那么我们是如何判断请求的中止状态呢?axios 为我们提供了一个 isCancel() 方法,用于判断请求的中止状态。isCancel() 方法的参数,就是我们在中止请求时自定义的信息。

方式二

通过传递一个 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('Operation canceled by the user.');

浏览器运行结果与方式一一致,此处不再赘述。

线上运行示例[6] (代码来源于MDN[7])

umi-request 中断请求

umi-request 基于 fetch 封装, 兼具 fetch 与 axios 的特点, 中止请求与 fetch 和 axios 一致不再过多赘述,详情可见官方文档 中止请求[8]

需要注意的是 AbortController 在低版本浏览器polyfill有问题,umi-request 在某些版本中并未提供 AbortController 的方式中止请求。

umi 项目中使用 CancelToken 中止请求

umi 项目中默认的请求库是umi-request,因此我们可以使用umi-request提供的方法来中止请求。另外,在umi项目中可以搭配使用了dva,因此下面简单介绍下在dva中使用CancelToken中止请求的流程。

1、在 services 目录下的文件中编写请求函数和取消请求的函数

import request from '@/utils/request';
const CancelToken = request.CancelToken;
let cancel: any;

// 合同文件上传 OSS
export async function uploadContractFileToOSS(postBody: Blob): Promise<any> {
  return request(`/fms/ossUpload/financial_sys/contractFile`, {
    method: "POST",
    data: postBody,
    requestType: 'form',
    // 传递一个 executor 函数到 CancelToken 的构造函数来创建一个 cancel token
    cancelToken: new CancelToken((c) => {
      cancel = c
    })
  })
}

// 取消合同文件上传
export async function cancelUploadFile() {
  return cancel && cancel()
}

2、在 models 中编写 Effect:

*uploadContractFileToOSS({ payload }: AnyAction, { call, put }: EffectsCommandMap): any {
  const response = yield call(uploadContractFileToOSS, payload);
  yield put({
    type: 'save',
    payload: {
      uploadOSSResult: response?.data,
    }
  })
  return response?.data
},

*cancelUploadFile(_: AnyAction, { call }: EffectsCommandMap): any {
  const response = yield call(cancelUploadFile)
  return response

},

3、在页面中通过dispatch函数触发相应的action:

// 发起请求
dispatch({
  type: 'contract/fetchContractFiles',
  payload: {
    contractId: `${id}`,
  }
})

// 取消请求
dispatch({
  type: "contract/cancelUploadFile"
})

4、在 utils/request.js 中统一处理中止请求的拦截:

const errorHandler = (error: { response: Response }): Response => {
  const { response } = error;
  notification.destroy()

  if (response && response.status) {
    const errorText = codeMessage[response.status] || response.statusText;
    const { status, url } = response;

    notification.error({
      message: `请求错误 ${status}: ${url}`,
      description: errorText,
    });
  } else if (error?.['type'] === 'TypeError') {
    notification.error({
      description: '您的网络发生异常,无法连接服务器',
      message: '网络异常',
    });
  } else if (error?.['request']?.['options']?.['cancelToken']) {
    notification.warn({
      description: '当前请求已被取消',
      message: '取消请求',
    });
  } else if (!response) {
    notification.error({
      description: '您的网络发生异常,无法连接服务器',
      message: '网络异常',
    });
  } else {
    notification.error({
      description: '请联系网站开发人员处理',
      message: '未知错误',
    });
  }
  return response;
};

作者:紫圣
https://juejin.cn/post/7033906910583586829
转载请注明出处

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《电子工程师必备: 元器件应用宝典(强化版)pdf》是一本对于电子工程师来说非常有价值的参考书。随着电子技术的不断发展和进步,元器件的种类和应用也越来越多样化和复杂化。这本书提供了详细的元器件的介绍和应用示例,帮助电子工程师更好地理解和应用不同的元器件。 这本宝典首先介绍了各种基本的被动元件,如电阻、电容和电感等。通过深入浅出的讲解,读者可以了解到这些元件的基本原理、特性和工作方式,并能够正确地选择和应用它们。而对于更复杂的主动元件,如晶体管、二极管和集成电路等,书中也提供了详细的说明和示例,帮助读者理解其内部结构和工作原理。书中还包含了各种元器件的参数和规格表,方便读者快速找到所需的信息。 此外,这本宝典还涵盖了不同元器件的常见应用场景和设计技巧。通过丰富的实例和图解,读者可以学习到如何在不同的电路中使用不同的元器件,以及如何解决常见的电路设计问题。同时,书中还介绍了一些常用的电路拓扑和设计方法,以及性能优化的技巧,帮助读者在实际应用中更好地发挥元器件的优势。 总而言之,《电子工程师必备: 元器件应用宝典(强化版)pdf》是一本全面而实用的电子工程参考书。无论是初学者还是有一定经验的电子工程师,都可以从中获得不少的启发和帮助。它不仅可以帮助读者更好地理解和应用各类元器件,还可以提供一些实用的设计技巧和经验,提高电子工程师的工作效率和设计水平。 ### 回答2: 《电子工程师必备:元器件应用宝典(强化版) pdf》是一本针对电子工程师而设计的重要参考书籍。 该书内容包括众多元器件的详尽介绍和应用指南。对于电子工程师来说,元器件是设计和制造电子产品的基础。掌握各种元器件的特性、参数和应用场景非常重要。这本宝典通过全面而系统的介绍,帮助读者了解不同类型的元器件,如二极管、晶体管、运算放大器、集成电路等。更重要的是,它提供了详细的应用指南,说明如何正确地选用和使用这些元器件。 此外,它还包含了元器件的特性曲线、电路图和应用实例,以帮助读者更好地理解和运用这些元器件。宝典中的精美图表和实例设计以简洁明了的方式解释了元器件的工作原理和使用技巧,使得读者易于理解和掌握。 对于电子工程师而言,这本宝典是他们建立知识体系和解决实际问题的重要工具。通过学习和应用宝典中的知识,电子工程师可以更高效地设计和优化电路,提高电子产品的性能和可靠性。 总之,电子工程师必备:元器件应用宝典(强化版) pdf是一本非常实用的参考资料,它可以帮助电子工程师更好地理解和应用各种元器件,提高设计和制造电子产品的技能水平。无论是初学者还是有经验的工程师,都可以从中受益。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值