溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何實(shí)現(xiàn)基于小程序請(qǐng)求接口wx.request封裝的類axios請(qǐng)求

發(fā)布時(shí)間:2020-07-02 14:32:57 來源:億速云 閱讀:436 作者:清晨 欄目:開發(fā)技術(shù)

這篇文章將為大家詳細(xì)講解有關(guān)如何實(shí)現(xiàn)基于小程序請(qǐng)求接口wx.request封裝的類axios請(qǐng)求,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

Introduction

  • wx.request 的配置、axios 的調(diào)用方式
  • 源碼戳我
     

feature

  • 支持 wx.request 所有配置項(xiàng)
  • 支持 axios 調(diào)用方式
  • 支持 自定義 baseUrl
  • 支持 自定義響應(yīng)狀態(tài)碼對(duì)應(yīng) resolve 或 reject 狀態(tài)
  • 支持 對(duì)響應(yīng)(resolve/reject)分別做統(tǒng)一的額外處理
  • 支持 轉(zhuǎn)換請(qǐng)求數(shù)據(jù)和響應(yīng)數(shù)據(jù)
  • 支持 請(qǐng)求緩存(內(nèi)存或本地緩存),可設(shè)置緩存標(biāo)記、過期時(shí)間

use

app.js @onLaunch

 import axios form 'axios'
 axios.creat({
 header: {
  content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
 },
 baseUrl: 'https://api.baseurl.com',
 ...
 });

page.js

axios
 .post("/url", { id: 123 })
 .then((res) => {
 console.log(response);
 })
 .catch((err) => {
 console.log(err);
 });

API

  axios(config) - 默認(rèn)get
  axios(url[, config]) - 默認(rèn)get
  axios.get(url[, config])
  axios.post(url[, data[, config]])
  axios.cache(url[, data[, config]]) - 緩存請(qǐng)求(內(nèi)存)
  axios.cache.storage(url[, data[, config]]) - 緩存請(qǐng)求(內(nèi)存 & local storage)
  axios.creat(config) - 初始化定制配置,覆蓋默認(rèn)配置

config

默認(rèn)配置項(xiàng)說明

export default {
 // 請(qǐng)求接口地址
 url: undefined,
 // 請(qǐng)求的參數(shù)
 data: {},
 // 請(qǐng)求的 header
 header: "application/json",
 // 超時(shí)時(shí)間,單位為毫秒
 timeout: undefined,
 // HTTP 請(qǐng)求方法
 method: "GET",
 // 返回的數(shù)據(jù)格式
 dataType: "json",
 // 響應(yīng)的數(shù)據(jù)類型
 responseType: "text",
 // 開啟 http2
 enableHttp2: false,
 // 開啟 quic
 enableQuic: false,
 // 開啟 cache
 enableCache: false,

 /** 以上為wx.request的可配置項(xiàng),參考 https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html */
 /** 以下為wx.request沒有的新增配置項(xiàng) */

 // {String} baseURL` 將自動(dòng)加在 `url` 前面,可以通過設(shè)置一個(gè) `baseURL` 便于傳遞相對(duì) URL
 baseUrl: "",
 // {Function} (同axios的validateStatus)定義對(duì)于給定的HTTP 響應(yīng)狀態(tài)碼是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者設(shè)置為 `null` 或 `undefined`),promise 將被 resolve; 否則,promise 將被 reject
 validateStatus: undefined,
 // {Function} 請(qǐng)求參數(shù)包裹(類似axios的transformRequest),通過它可統(tǒng)一補(bǔ)充請(qǐng)求參數(shù)需要的額外信息(appInfo/pageInfo/場(chǎng)景值...),需return data
 transformRequest: undefined,
 // {Function} resolve狀態(tài)下響應(yīng)數(shù)據(jù)包裹(類似axios的transformResponse),通過它可統(tǒng)一處理響應(yīng)數(shù)據(jù),需return res
 transformResponse: undefined,
 // {Function} resolve狀態(tài)包裹,通過它可做接口resolve狀態(tài)的統(tǒng)一處理
 resolveWrap: undefined,
 // {Function} reject狀態(tài)包裹,通過它可做接口reject狀態(tài)的統(tǒng)一處理
 rejectWrap: undefined,
 // {Boolean} _config.useCache 是否開啟緩存
 useCache: false,
 // {String} _config.cacheName 緩存唯一key值,默認(rèn)使用url&data生成
 cacheName: undefined,
 // {Boolean} _config.cacheStorage 是否開啟本地緩存
 cacheStorage: false,
 // {Any} _config.cacheLabel 緩存標(biāo)志,請(qǐng)求前會(huì)對(duì)比該標(biāo)志是否變化來決定是否使用緩存,可用useCache替代
 cacheLabel: undefined,
 // {Number} _config.cacheExpireTime 緩存時(shí)長(zhǎng),計(jì)算緩存過期時(shí)間,單位-秒
 cacheExpireTime: undefined,
};

實(shí)現(xiàn)

axios.js

import Axios from "./axios.class.js";

// 創(chuàng)建axios實(shí)例
const axiosInstance = new Axios();
// 獲取基礎(chǔ)請(qǐng)求axios
const { axios } = axiosInstance;
// 將實(shí)例的方法bind到基礎(chǔ)請(qǐng)求axios上,達(dá)到支持請(qǐng)求別名的目的
axios.creat = axiosInstance.creat.bind(axiosInstance);
axios.get = axiosInstance.get.bind(axiosInstance);
axios.post = axiosInstance.post.bind(axiosInstance);
axios.cache = axiosInstance.cache.bind(axiosInstance);
axios.cache.storage = axiosInstance.storage.bind(axiosInstance);

Axios class

初始化

  • defaultConfig 默認(rèn)配置,即 defaults.js
  • axios.creat 用戶配置覆蓋默認(rèn)配置
  • 注意配置初始化后 mergeConfig 不能被污染,config 需通過參數(shù)傳遞
constructor(config = defaults) {
 this.defaultConfig = config;
 }
creat(_config = {}) {
 this.defaultConfig = mergeConfig(this.defaultConfig, _config);
}

請(qǐng)求別名

  • axios 兼容 axios(config) 或 axios(url[, config]);
  • 別名都只是 config 合并,最終都通過 axios.requst()發(fā)起請(qǐng)求;
 axios($1 = {}, $2 = {}) {
 let config = $1;
 // 兼容axios(url[, config])方式
 if (typeof $1 === 'string') {
  config = $2;
  config.url = $1;
 }
 return this.request(config);
 }

 post(url, data = {}, _config = {}) {
 const config = {
  ..._config,
  url,
  data,
  method: 'POST',
 };
 return this.request(config);
 }

請(qǐng)求方法 _request

請(qǐng)求配置預(yù)處理

  • 實(shí)現(xiàn) baseUrl
  • 實(shí)現(xiàn) transformRequest(轉(zhuǎn)換請(qǐng)求數(shù)據(jù))
 _request(_config = {}) {
 let config = mergeConfig(this.defaultConfig, _config);
 const { baseUrl, url, header, data = {}, transformRequest } = config;
 const computedConfig = {
  header: {
  'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
  ...header,
  },
  ...(baseUrl && {
  url: combineUrl(url, baseUrl),
  }),
  ...(transformRequest &&
  typeof transformRequest === 'function' && {
   data: transformRequest(data),
  }),
 };
 config = mergeConfig(config, computedConfig);
 return wxRequest(config);
 }

wx.request

發(fā)起請(qǐng)求、處理響應(yīng)

  • 實(shí)現(xiàn) validateStatus(狀態(tài)碼映射 resolve)
  • 實(shí)現(xiàn) transformResponse(轉(zhuǎn)換響應(yīng)數(shù)據(jù))
  • 實(shí)現(xiàn) resolveWrap、rejectWrap(響應(yīng)狀態(tài)處理)
export default function wxRequest(config) {
 return new Promise((resolve, reject) => {
 wx.request({
  ...config,
  success(res) {
  const {
   resolveWrap,
   rejectWrap,
   transformResponse,
   validateStatus,
  } = config;
  if ((validateStatus && validateStatus(res)) || ifSuccess(res)) {
   const _resolve = resolveWrap ? resolveWrap(res) : res;
   return resolve(
   transformResponse ? transformResponse(_resolve) : _resolve
   );
  }
  return reject(rejectWrap ? rejectWrap(res) : res);
  },
  fail(res) {
  const { rejectWrap } = config;
  reject(rejectWrap ? rejectWrap(res) : res);
  },
 });
 });
}

請(qǐng)求緩存的實(shí)現(xiàn)

  • 默認(rèn)使用內(nèi)存緩存,可配置使用 localStorage
  • 封裝了 Storage 與 Buffer 類,與 Map 接口一致:get/set/delete
  • 支持緩存標(biāo)記&過期時(shí)間
  • 緩存唯一 key 值,默認(rèn)使用 url&data 生成,無需指定
 import Buffer from '../utils/cache/Buffer';
 import Storage from '../utils/cache/Storage';
 import StorageMap from '../utils/cache/StorageMap';


 /**
 * 請(qǐng)求緩存api,緩存于本地緩存中
 */
 storage(url, data = {}, _config = {}) {
 const config = {
  ..._config,
  url,
  data,
  method: 'POST',
  cacheStorage: true,
 };
 return this._cache(config);
 }

 /**
 * 請(qǐng)求緩存
 * @param {Object} _config 配置
 * @param {Boolean} _config.useCache 是否開啟緩存
 * @param {String} _config.cacheName 緩存唯一key值,默認(rèn)使用url&data生成
 * @param {Boolean} _config.cacheStorage 是否開啟本地緩存
 * @param {Any} _config.cacheLabel 緩存標(biāo)志,請(qǐng)求前會(huì)對(duì)比該標(biāo)志是否變化來決定是否使用緩存,可用useCache替代
 * @param {Number} _config.cacheExpireTime 緩存時(shí)長(zhǎng),計(jì)算緩存過期時(shí)間,單位-秒
 */
 _cache(_config) {
 const {
  url = '',
  data = {},
  useCache = true,
  cacheName: _cacheName,
  cacheStorage,
  cacheLabel,
  cacheExpireTime,
 } = _config;
 const computedCacheName = _cacheName || `${url}#${JSON.stringify(data)}`;
 const cacheName = StorageMap.getCacheName(computedCacheName);

 // return buffer
 if (useCache && Buffer.has(cacheName, cacheLabel)) {
  return Buffer.get(cacheName);
 }

 // return storage
 if (useCache && cacheStorage) {
  if (Storage.has(cacheName, cacheLabel)) {
  const data = Storage.get(cacheName);
  // storage => buffer
  Buffer.set(
   cacheName,
   Promise.resolve(data),
   cacheExpireTime,
   cacheLabel
  );
  return Promise.resolve(data);
  }
 }
 const curPromise = new Promise((resolve, reject) => {
  const handleFunc = (res) => {
  // do storage
  if (useCache && cacheStorage) {
   Storage.set(cacheName, res, cacheExpireTime, cacheLabel);
  }
  return res;
  };

  this._request(_config)
  .then((res) => {
   resolve(handleFunc(res));
  })
  .catch(reject);
 });

 // do buffer
 Buffer.set(cacheName, curPromise, cacheExpireTime, cacheLabel);

 return curPromise;
 }

關(guān)于如何實(shí)現(xiàn)基于小程序請(qǐng)求接口wx.request封裝的類axios請(qǐng)求就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI