小知识,大挑战!本文正在参与「程序员必备小知识」创作活动
由于之前项目中需要使用 cancelToken 来取消接口,所以研究了一下 cancelToken 怎么使用,并且对源码进行了一定了解。
cancelToken 的使用 -> 「传送门」
在这里记录一下我的理解,希望也能对大家有些帮助。
axios/lib/cancel/cancelToken.js
// 一下是 cancelToken.js 的源码
// 为了内容不要太长,一些感觉不太重要的部分被我删除了
var Cancel = require('./Cancel');
function CancelToken(executor) {
var resolvePromise;
this.promise = new Promise(function promiseExecutor(resolve) {
// 将 Promise 的 resolve 方法赋值给 resolvePromise
// 这样 resolvePromise 方法就可以在外部控制当前这个 Promise 的状态
// 在外部调用 resolvePromise 就可以将 当前的 Promise 的状态推到 fullfilled
resolvePromise = resolve;
});
// 在传入的函数中调用 resolvePromise
// 这样就把 resolvePromise( 控制 Promise 状态的方法 )的控制权传递到外部
// 即在外部通过 new CancelToken 创建 CancelToken对象时可以通过传参,取得这个 Promise 对象的控制权
var token = this;
// token 指向当前创建的 CancelToken 对象
executor(function cancel(message) {
if (token.reason) {
// Cancellation has already been requested
return;
}
// Cancel 构造函数比较简单,就是给 Cancel 对象添加一个 message 属性
// 用于在取消接口的时候有一个信息的输出
token.reason = new Cancel(message);
resolvePromise(token.reason);
});
}
// CancelToken.source 方法会构建一个 CancelToken 对象,并返回一个有两个参数的对象( token、cancel )
// token -> 指向构建出的 CancelToken 对象
// cancel -> 取消请求需要调用的方法
CancelToken.source = function source() {
var cancel;
var token = new CancelToken(function executor(c) {
cancel = c;
});
return {
token: token,
cancel: cancel
};
};
module.exports = CancelToken;
axios/lib/adapters/http.js
在 http.js 中关于 CancelToken 的内容只有下面一小段
if (config.cancelToken) {
// 先校验了 cancelToken
// 定义了 promise.then,即当 promise 的状态转变为 fullfilled 时执行的内容
config.cancelToken.promise.then(function onCanceled(cancel) {
if (req.aborted) return;
req.abort();
reject(cancel);
});
}
个人理解
其实 CancelToken 的内容还是比较简单的,核心还是将 promise 的控制权通过参数的形式传递到外部,是使用者可以独立控制 promise 的状态,进而去控制接口;
// 小demo
let promiseFun = null
function promiseBtn() {
let promise = new Promise((resolve) => {
promiseFun = resolve;
});
promise.then((txt) => {
alert(txt)
})
console.log(promise)
setTimeout(() => {
promiseFun('取消');
}, 3000);
},