mobx-state-tree icon indicating copy to clipboard operation
mobx-state-tree copied to clipboard

Add an `aliveFlow` that only calls `.next()` when the tree is still alive

Open weiwei-lin opened this issue 2 years ago • 0 comments

Feature request

Add an aliveFlow that only calls .next() when the tree is still alive. Also add something like the following to the async action doc. CAVEAT: when running an async action, the tree might be destroyed before the promise is resolved, leading to errors.

Is your feature request related to a problem? Please describe.

This is very useful when running async actions on tree nodes that might be replaced. For instance, I might have a SessionStore that fetch and update the session token automatically when it expires. If the SessionStore is replaced (e.g. due to user switching to a different account), I'd love to abort any running async actions.

Note that this is different from #691 which requires cancelling the flow manually. #691 is less ergonomic when the flow is attached to a lifecycle hook.

Describe the solution you'd like

It can be implemented as

export function aliveFlow<R, Args extends any[]>(
    self: IAnyStateTreeNode,
    generator: Parameters<typeof flow<R, Args>>[0],
): ReturnType<typeof flow<R, Args>> {
  return flow(function* (...args) {
    const gen = generator(...args);
    let next = gen.next();
    while (!next.done) {
      const resolved = yield next.value;
      if (!isAlive(self)) {
        yield Promise.race([]);
      }
      next = gen.next(resolved);
    }
    return next.value;
  });
}

Are you willing to (attempt) a PR?

  • [x] Yes
  • [ ] No

weiwei-lin avatar Aug 24 '22 12:08 weiwei-lin