Skip to content

Commit 59e1242

Browse files
committed
feat(cancellation): allow fork to chain so cancel can be called after
1 parent 622228c commit 59e1242

File tree

3 files changed

+52
-30
lines changed

3 files changed

+52
-30
lines changed

docs/task-instance.md

+22
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,28 @@
22

33
The `Task` class is the core of this library. Below are all the methods that can be called on a task. To create a new task, refer to [Creating Tasks](docs/task-static.md).
44

5+
## cancel
6+
7+
Cancels a task, meaning it will never complete.
8+
9+
{% tabs %}
10+
{% tab title="Usage" %}
11+
12+
```typescript
13+
const task = Task.of(5).cancel();
14+
```
15+
16+
{% endtab %}
17+
18+
{% tab title="Type Definition" %}
19+
20+
```typescript
21+
type cancel = () => void;
22+
```
23+
24+
{% endtab %}
25+
{% endtabs %}
26+
527
## map
628

729
Given a task, when it has _succeeded_, pass the value through a mapping function.

src/Task/Task.ts

+20-20
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* eslint-disable @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-explicit-any, @typescript-eslint/no-use-before-define */
1+
/* eslint-disable @typescript-eslint/no-misused-promises, @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-explicit-any, @typescript-eslint/no-use-before-define */
22
import { constant, identity, range } from "../util";
33

44
export type Reject<E> = (error: E) => void;
@@ -37,27 +37,27 @@ export class Task<E, S> implements PromiseLike<S> {
3737
public static flatten = flatten;
3838

3939
public isCanceled = false;
40-
public fork: Fork<E, S>;
40+
constructor(private computation: Fork<E, S>) {}
4141

42-
constructor(computation: Fork<E, S>) {
43-
this.fork = (reject: Reject<E>, resolve: Resolve<S>) => {
44-
if (this.isCanceled) {
45-
return;
46-
}
42+
fork(reject: Reject<E>, resolve: Resolve<S>) {
43+
if (this.isCanceled) {
44+
return this;
45+
}
4746

48-
computation(
49-
err => {
50-
if (!this.isCanceled) {
51-
reject(err);
52-
}
53-
},
54-
value => {
55-
if (!this.isCanceled) {
56-
resolve(value);
57-
}
47+
this.computation(
48+
err => {
49+
if (!this.isCanceled) {
50+
reject(err);
5851
}
59-
);
60-
};
52+
},
53+
value => {
54+
if (!this.isCanceled) {
55+
resolve(value);
56+
}
57+
}
58+
);
59+
60+
return this;
6161
}
6262

6363
cancel() {
@@ -313,7 +313,7 @@ export function fork<E, S>(
313313
reject: Reject<E>,
314314
resolve: Resolve<S>,
315315
task: Task<E, S>
316-
): void {
316+
): Task<E, S> {
317317
return task.fork(reject, resolve);
318318
}
319319

src/Task/__tests__/cancellation.spec.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ describe("cancellation", () => {
88
const resolve = jest.fn();
99
const reject = jest.fn();
1010

11-
const task = succeedIn(1000, SUCCESS_RESULT);
12-
task.cancel();
13-
task.fork(reject, resolve);
11+
succeedIn(1000, SUCCESS_RESULT)
12+
.fork(reject, resolve)
13+
.cancel();
14+
15+
jest.runAllTimers();
1416

1517
expect(resolve).not.toBeCalled();
1618
expect(reject).not.toBeCalled();
17-
18-
jest.runAllTimers();
1919
});
2020

2121
test("should be able to cancel a failed task", () => {
@@ -24,13 +24,13 @@ describe("cancellation", () => {
2424
const resolve = jest.fn();
2525
const reject = jest.fn();
2626

27-
const task = failIn(1000, ERROR_RESULT);
28-
task.cancel();
29-
task.fork(reject, resolve);
27+
failIn(1000, ERROR_RESULT)
28+
.fork(reject, resolve)
29+
.cancel();
30+
31+
jest.runAllTimers();
3032

3133
expect(resolve).not.toBeCalled();
3234
expect(reject).not.toBeCalled();
33-
34-
jest.runAllTimers();
3535
});
3636
});

0 commit comments

Comments
 (0)