关键代码

JavaScript
JavaScript
'use strict';
module.exports = function xhrAdapter(config) {
  return new Promise(function dispatchXhrRequest(resolve, reject) {
    // ......
    //创建请求对象
    var request = new XMLHttpRequest();
    request.open(
      config.method.toUpperCase(), 
      buildURL(fullPath, config.params, config.paramsSerializer), 
      true
    );
    // ......
    // 设置超时时间
    request.timeout = config.timeout;

    //绑定事件
    request.onreadystatechange = function handleLoad() {
      // ......
      // 拼接响应的结果
      var response = {
        data: responseData,
        status: request.status,
        statusText: request.statusText,
        headers: responseHeaders,
        config: config,
        request: request
      };
      //根据响应修改 promise 的状态
      settle(resolve, reject, response);
      // Clean up request
      request = null;
    };

    request.onabort = function handleAbort() {
      if (!request) {
        return;
      }
      reject(createError('Request aborted', config, 'ECONNABORTED', request));
      // Clean up request
      request = null;
    };

    // 如果配置了 cancelToken 则调用 then 方法设置成功的回调
    if (config.cancelToken) {
      config.cancelToken.promise.then(function onCanceled(cancel) {
        if (!request) {
          return;
        }
        //取消请求
        request.abort();
        reject(cancel);
        request = null;
      });
    }
    if (requestData === undefined) {
      requestData = null;
    }

    request.send(requestData);
  });
};
function CancelToken(executor) {
  // 执行器函数必须是一个函数
  if (typeof executor !== 'function') {
    throw new TypeError('executor must be a function.');
  }

  var resolvePromise;
  // 实例对象身上添加 promise 属性
  this.promise = new Promise(function promiseExecutor(resolve) {
    // 将修改 promise 对象成功状态的函数暴露出去
    resolvePromise = resolve;
  });

  var token = this;
  //将修改 promise 状态的函数暴露出去, 通过 cancel = c 可以将函数赋值给 cancel
  executor(function cancel(message) {
    if (token.reason) {
      return;
    }
    token.reason = new Cancel(message);
    resolvePromise(token.reason);
  });
}

总结

  1. 当配置了 cancelToken 对象时,new axios.CancelToken 实例化,实例挂载到 axios 的 cancelToken 配置项上, 保存 cancel 函数;

  2. CancelToken 实例化过程:

    • CancelToken 构造函数方式执行,将 executor 参数 function © { cancel = c } 传入;
    • promise = new Promise, 将 promise 挂载 CancelToken 实例上,并将修改 promise 状态的 resolve 方法传递出去;
    • 执行 executor 执行器,将修改 promise 状态的方法传递给了外部的 cancel;
  3. 发送 xhr/http 请求:

    • 若 config 配置了 CancelToken 配置项,判断 config.CancelToken.promise 状态,成功状态会执行config.CancelToken.promise.then 方法;
    • then 方法会调用 xhr.abort() 直接中止请求(请求未完成才能中止);
  4. 调用 cancel() 取消请求:

    • 执行 cacel 函数, 传入错误信息 message;
    • config.CancelToken.promise 状态为成功,中止请求并让发请求的 proimse 失败;
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 关键代码
  2. 2. 总结