All files / src/adapters wx-adapter.ts

93.1% Statements 54/58
81.81% Branches 18/22
100% Functions 6/6
93.1% Lines 54/58

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 1181x 1x 1x 1x                 1x   149x 149x 149x 149x               149x 894x   149x   149x 149x 149x   149x 149x 149x 149x 149x 149x   149x 114x         114x 342x 114x 114x 114x 114x 114x   114x   114x 103x   11x 11x       149x   35x       35x       149x             149x       149x 149x 42x       36x 36x 36x 36x           149x 6x       3x 3x 3x 3x             1x  
import { InternalAxiosRequestConfig, AxiosPromise, AxiosError } from 'axios';
import { buildFullPath, deepCopy, generateRequestHash } from '../utils';
import { addCanceller, deleteCalledCancellerByHash, deleteCancellerByHash, hasCalledCancelerRecord } from '../canceller'
import { addRequestCanceler, clearCancelerByHash } from '../cancelLastSameRequest'
 
declare const wx: any;
 
type WxErr = {
  errMsg: string;
  errno: string;
}
 
export default function wxAdapter(config: InternalAxiosRequestConfig): AxiosPromise {
  // adapter接受的config要完全符合axios的配置规范,然后在这里针对不同的引擎做个性化修改
  return new Promise((resolve, reject) => {
    let requestConfig = {} as any;
    let isAborted = false
    let requestTask: any = null
    const {
      headers,
      data,
      params,
      url,
      timeout,
      method,
      ...rest
    } = config;
 
    const requestHash = generateRequestHash(config)
 
    const requestHeader = deepCopy(headers);
    delete requestHeader.Referer; // 小程序文档,header中不能有Referer
    requestConfig.header = requestHeader;
 
    const requestData = data || params; // wx环境,不论get还是post,参数传递的属性名均为data
    requestConfig.data = deepCopy(requestData);
    requestConfig.url = buildFullPath(config.baseURL || '', url || '');
    requestConfig.timeout = timeout;
    requestConfig.method = method?.toUpperCase();
    requestConfig = { ...requestConfig, ...rest };
 
    requestConfig.success = (res: any) => {
      let response = {} as any;
      const {
        data: resData,
        statusCode,
        header,
        ...restRes
      } = res;
      response.data = resData;
      response.status = statusCode;
      response.headers = header;
      response.config = config;
      response = { ...response, ...restRes };
 
      const { validateStatus } = response.config;
 
      if (!response.status || !validateStatus || validateStatus(response.status)) {
        resolve(response);
      } else {
        const errMsg = `Request failed with status code ${response.status}`
        reject(new AxiosError(errMsg, '', requestConfig, requestTask, response));
      }
    };
 
    requestConfig.fail = (err: WxErr) => {
 
      Iif (isAborted) {
        reject(new AxiosError(err.errMsg, AxiosError.ERR_CANCELED, requestConfig, requestTask))
      }
 
      reject(new AxiosError(err.errMsg, err.errno, requestConfig, requestTask));
    };
 
    // 判断是否已经调用了取消函数
    Iif (hasCalledCancelerRecord(requestConfig.cancelKey, requestHash)) {
      // 已经调用过取消函数了,直接抛出错误即可
      reject(new AxiosError('请求在发出之前被主动取消!', AxiosError.ERR_CANCELED, requestConfig, requestTask))
      // 删除记录
      deleteCalledCancellerByHash(requestConfig.cancelKey, requestHash)
      return
    }
    requestTask = wx.request(requestConfig);
 
    // 手动取消请求功能
    // 设置了cancelKey,但是环境不支持AbortController
    if ('undefined' === typeof AbortController) {
      if (requestConfig.cancelKey) {
        addCanceller(
          requestConfig.cancelKey,
          requestHash,
          () => {
            isAborted = true
            requestTask.abort.call(requestTask)
            deleteCancellerByHash(requestConfig.cancelKey, requestHash)
            reject(new AxiosError('请求被取消!', AxiosError.ERR_CANCELED, requestConfig, requestTask))
          }
        )
      }
 
      // 取消上一个相同URL的get请求功能
      if (requestConfig.cancelLastSameUrl && requestConfig.method.toLocaleLowerCase() === 'get') {
        addRequestCanceler(
          config.url as string,
          requestHash,
          () => {
            isAborted = true
            requestTask.abort.call(requestTask)
            clearCancelerByHash(config.url as string, requestHash)
            reject(new AxiosError('请求被取消!', AxiosError.ERR_CANCELED, requestConfig, requestTask))
          }
        )
      }
    }
  });
}
wxAdapter.type = 'wx'