# 1. 前言

实现了第二种使用方式,再实现第一种使用方式就非常简单了,我们说过,第一种使用方式就是对第二种使用方式的一种高级包装罢了。在总体思路那一篇文章中我们分析过:相比较第二种使用方式,第一种方式就是在CancelToken类里面增加了一个类可以调用的静态方法source,然后把变量cancel定义在了静态方法source内部,并且在source内部把CancelToken类实例好,最后组成对象一并返回。

有了思路以后,接下里,我们就来实现第一种使用方式。

# 2. 接口类型定义

由于我们需要给CancelToken类内增加静态方法source,所以我们先来修改CancelToken类的类类型定义,在其内部增加source方法,如下:

export interface CancelTokenStatic {
  new (executor: CancelExecutor): CancelToken;
  source(): CancelTokenSource;
}
1
2
3
4

source方法返回的是一个对象,里面包含两个属性,分别是:CancelToken类的实例对象token,类型是CancelToken和触发函数cancel,类型是Canceler

export interface CancelTokenSource {
  token: CancelToken;
  cancel: Canceler;
}
1
2
3
4

# 3. 实现 source 方法

接口定义好之后,我们就可以在CancelToken类中实现source方法啦。

static source():CancelTokenSource{
    let cancel!:Canceler;
    let token = new CancelToken(c => {
        cancel = c
    })
    return {
        cancel,
        token
    }
}
1
2
3
4
5
6
7
8
9
10

source 的静态方法实现很简单,就是第二种方式的显示实例化CancelToken 类挪到类里面来,并且把cancel变量也挪到里面来,然后分别把实例对象赋给token,触发函数赋给cancel,一并返回出去。这样在外面使用的时候:

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get("/user/12345", {
  cancelToken: source.token,
  //  对应下面的
  //cancelToken: new CancelToken(function executor(c) {
  //  cancel = c;
  //})
});

source.cancel("Operation canceled by the user.");
// 对应下面的
//cancel();
1
2
3
4
5
6
7
8
9
10
11
12
13
14

OK,第一种使用方式就实现好了,是不是很简单,其余东西都跟上篇文章中的第二种实现方式一样。接下来,我们就编写demo来测试下效果。

# 4. demo 编写

我们继续沿用上篇文章的demo,只需在src/examples/cancel/app.ts文件中添加上本篇文章实现的第一种取消请求的使用方式即可,如下:

const source = CancelToken.source();

axios
  .get("/api/cancel", {
    cancelToken: source.token,
  })
  .catch(function(e) {
    console.log(e);
  });

setTimeout(() => {
  source.cancel("Operation canceled by the user");
}, 1000);
1
2
3
4
5
6
7
8
9
10
11
12
13

然后运行项目,我们打开 chrome 浏览器,访问 http://localhost:8000/ (opens new window) 即可访问我们的 demo 了,我们点击 cancel,通过F12network 部分我们可以看到:请求发出一秒后请求状态变成canceled,表明请求已经被成功取消了。

然后我们将demo中的取消请求触发函数注释,

//setTimeout(() => {
//  source.cancel("Operation canceled by the user");
//}, 1000);
1
2
3

再发送请求,我们看到 3 秒后请求又可以正常得到响应了。

OK,取消请求的第一种使用方式就已经实现完毕了。