关键代码
'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);
});
}
总结
-
当配置了 cancelToken 对象时,new axios.CancelToken 实例化,实例挂载到 axios 的 cancelToken 配置项上, 保存 cancel 函数;
-
CancelToken 实例化过程:
- CancelToken 构造函数方式执行,将 executor 参数 function © { cancel = c } 传入;
- promise = new Promise, 将 promise 挂载 CancelToken 实例上,并将修改 promise 状态的 resolve 方法传递出去;
- 执行 executor 执行器,将修改 promise 状态的方法传递给了外部的 cancel;
-
发送 xhr/http 请求:
- 若 config 配置了 CancelToken 配置项,判断 config.CancelToken.promise 状态,成功状态会执行config.CancelToken.promise.then 方法;
- then 方法会调用 xhr.abort() 直接中止请求(请求未完成才能中止);
-
调用 cancel() 取消请求:
- 执行 cacel 函数, 传入错误信息 message;
- config.CancelToken.promise 状态为成功,中止请求并让发请求的 proimse 失败;
请求、响应数据转换器
上一篇