前言
咱们可能会遇到这样的场景:当用户切换页面时,上个页面存在pending中的申请。千里之行;始于足下,如此会造成性能节约,减少服务器压力。本文在于分享基于小程序提供的申请api及 axios 应用中如何勾销不必要的申请。
基于Promise的requestTask封装
// request.jsfunction request(opt) { const conf = { ... } let reqTask = null // 保留 request 返回值,并挂载到 promise 上 const promise = new Promise((resolve, reject) => { reqTask = request({ ...conf, success(res) { const { data } = res // ... return resolve(data) }, fail(err) { return reject(err) }, }) }) promise.reqTask = reqTask return promise}export default request
// api.jsimport request from './request'export function fetchData() { return request({ ... })}
// index.jsimport * as api from '../../api';async fetchData() { // 个别调用 await api.fetchData().then(response => { ... });},// usageasync fetchOtherData() { const promise = api.fetchOtherData({ ... }); globalData['reqTask'] = promise.reqTask // 将 requestTask 挂到全局 await promise.then(response => { ... });},
<script>export default { methods: { handleClick() { this.reqTask?.abort() // 勾销申请 }, },}</script>
cancel token的应用
通过传递一个 executor 函数到 CancelToken 的构造函数来创立 cancel token
// file.jsimport axios from 'axios'uploadFile(context, files) { const CancelToken = axios.CancelToken for (let i = 0; i < files.length; i++) { const file = files[i] const promise = axios .post('api', data, { cancelToken: new CancelToken(function executor(c) { // executor 函数接管一个 cancel 函数作为参数 file.cancel = c // 全局挂载多个 cancel token const cancels = [] cancels.push(c) globalData['cancels'] = cancels }), }) .then(response => { ... }) .catch(thrown => { if (axios.isCancel(thrown)) console.log('Request canceled', thrown.message); else { // 处理错误 } })},
// index.vue<template> <div> <div v-for="file in files" :key="file.id"> <!-- cancel the request --> <div @click="file.cancel" /> </div> </div></template><script>export default { methods: { handleClick() { // 勾销多个申请 for (let i = 0; i < this.cancels.length; i++) { this.cancels[i]() } }, },}</script>
refs
改良异步封装:解决带返回值的异步调用
axios中文文档