ngneat / until-destroy

🦊 RxJS operator that unsubscribe from observables on destroy
https://netbasal.com/
MIT License
1.74k stars 100 forks source link

Add a util cancel Promises #200

Closed camsteffen closed 2 years ago

camsteffen commented 2 years ago

I know I know you can't cancel a Promise. But you can create a Promise that never resolves using the Promise constructor. So my idea is to create a util that effectively cancels a Promise when the component is destroyed. Some people say that Observable is strictly better than Promise, but I would suggest that it depends on your use case. Sometimes a Promise does all you need and with less code. This utility would make Promises good enough in even more scenarios. And then you get async/await syntax.

Usage example:

const stuff = await unlessDestroyed(fetch('http://example.com/stuff'));
console.log("Fetched stuff. The component was not destroyed.");

Possible implementation:

/// Returns a new promise that resolves the same as the provided
/// promise, unless the component is destroyed first, in which
/// case the returned promise will never resolve.
function unlessDestroyed<T>(promise: Promise<T>): Promise<T> {
  return new Promise((resolve, reject) => {
    let destroyed = false;
    const destroySub = destroySubject.subscribe(() => {
      destroyed = true;
    });

    function finish<U>(callback: (u: U) => void) {
      return (data: U) => {
        destroySub.unsubscribe();
        if (!destroyed) {
          callback(data);
        }
      };
    }
    promise.then(finish(resolve), finish(reject))
  });
}