Skip to content

Commit 5e2bcbd

Browse files
remove derived mounted property and improve cancellation
1 parent 311b827 commit 5e2bcbd

File tree

1 file changed

+20
-30
lines changed

1 file changed

+20
-30
lines changed

modules/Coroutine.js

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,59 +8,42 @@ function create(coroutine) {
88
super(props);
99
this.state = { view: null };
1010
this.iterator = null;
11-
this.mounted = false;
1211
}
1312

1413
iterate(props) {
1514
let target = coroutine(props);
1615

1716
this.iterator = target;
1817

19-
let updater = view => {
20-
if (this.mounted && this.iterator === target) {
21-
this.setState({ view });
22-
}
23-
};
18+
let shouldStop = () => this.iterator !== target;
19+
let updateView = view => this.setState({ view });
2420

2521
if (isPromiseLike(target)) {
2622
// coroutine is Async Function, awaiting for the final result
27-
return target.then(updater);
23+
return target.then(value => shouldStop() || updateView(value));
2824
} else {
2925
let step = this.iterator.next();
3026

3127
if (isPromiseLike(step)) {
3228
// coroutine is Async Generator, rendering every time it yields
33-
return resolveAsyncIterator(this.iterator, step, updater);
29+
return resolveAsyncIterator(this.iterator, step, updateView, shouldStop);
3430
} else {
3531
// coroutine is Sync Generator, rendering the final result, awaiting yielded promises
36-
return resolveSyncIterator(this.iterator, step, updater);
32+
return resolveSyncIterator(this.iterator, step, updateView, shouldStop);
3733
}
3834
}
3935
}
4036

4137
componentDidMount() {
42-
this.mounted = true;
4338
return this.iterate(this.props);
4439
}
4540

4641
componentDidUpdate(prevProps) {
47-
if (!arePropsEqual(this.props, prevProps)) {
48-
if (this.iterator && this.iterator.return) {
49-
this.iterator.return();
50-
}
51-
52-
if (this.mounted) {
53-
this.iterate(this.props);
54-
}
55-
}
42+
return arePropsEqual(this.props, prevProps) || this.iterate(this.props);
5643
}
5744

5845
componentWillUnmount() {
59-
if (this.iterator && this.iterator.return) {
60-
this.iterator.return();
61-
}
62-
63-
this.mounted = false;
46+
this.iterator = null;
6447
}
6548

6649
render() {
@@ -73,29 +56,36 @@ function create(coroutine) {
7356
return Coroutine;
7457
}
7558

76-
function resolveSyncIterator(i, step, cb) {
59+
function resolveSyncIterator(i, step, cb, shouldStop) {
60+
if (shouldStop()) {
61+
return i.return();
62+
}
7763
if (!step.done) {
7864
if (isPromiseLike(step.value)) {
7965
return step.value
80-
.then(data => resolveSyncIterator(i, i.next(data), cb))
81-
.catch(error => resolveSyncIterator(i, i.throw(error), cb));
66+
.then(data => resolveSyncIterator(i, i.next(data), cb, shouldStop))
67+
.catch(error => resolveSyncIterator(i, i.throw(error), cb, shouldStop));
8268
} else {
8369
let isErrorLike = step.value instanceof Error;
8470
let nextStep = isErrorLike ? i.throw(step.value) : i.next(step.value);
85-
return resolveSyncIterator(i, nextStep, cb);
71+
return resolveSyncIterator(i, nextStep, cb, shouldStop);
8672
}
8773
} else {
8874
return cb(step.value);
8975
}
9076
}
9177

92-
function resolveAsyncIterator(i, step, cb) {
78+
function resolveAsyncIterator(i, step, cb, shouldStop) {
9379
step.then(data => {
80+
if (shouldStop()) {
81+
return i.return();
82+
}
83+
9484
if (data.value !== undefined) {
9585
cb(data.value);
9686
}
9787

98-
return !data.done && resolveAsyncIterator(i, i.next(), cb);
88+
return !data.done && resolveAsyncIterator(i, i.next(), cb, shouldStop);
9989
});
10090
}
10191

0 commit comments

Comments
 (0)