DEV Community

Discussion on: An elegant solution for memory leaks in React

Collapse
 
mohantejach profile image
mohantejach • Edited

an improved version of the above code : link

const PromiseObserver = new EventEmitter();

class AsyncAbort {
  constructor() {
    this.id = `async_${getRandomString(10)}`;
    this.asyncFun = null;
    this.asyncFunParams = [];
    this.thenBlock = null;
    this.catchBlock = null;
    this.finallyBlock = null;
  }

  addCall(asyncFun, params) {
    this.asyncFun = asyncFun;
    this.asyncFunParams = params;
    return this;
  }

  addThen(callback) {
    this.thenBlock = callback;
    return this;
  }

  addCatch(callback) {
    this.catchBlock = callback;
    return this;
  }

  addFinally(callback) {
    this.finallyBlock = callback;
    return this;
  }

  call() {
    const callback = ({ type, value }) => {
      switch (type) {
        case "then":
          if (this.thenBlock) this.thenBlock(value);
          break;
        case "catch":
          if (this.catchBlock) this.catchBlock(value);
          break;
        case "finally":
          if (this.finallyBlock) this.finallyBlock(value);
          break;
        default:
      }
    };
    PromiseObserver.addListener(this.id, callback);
    const cancel = () => {
      PromiseObserver.removeAllListeners(this.id);
    };
    this.asyncFun(...this.asyncFunParams)
      .then((resp) => {
        PromiseObserver.emit(this.id, { type: "then", value: resp });
      })
      .catch((error) => {
        PromiseObserver.emit(this.id, { type: "catch", value: error });
      })
      .finally(() => {
        PromiseObserver.emit(this.id, { type: "finally" });
        PromiseObserver.removeAllListeners(this.id);
      });
    return cancel;
  }
}

Enter fullscreen mode Exit fullscreen mode

in the useEffect hook you can do

React.useEffect(() => {
    const abort = new AsyncAbort()
      .addCall(simulateSlowNetworkRequest, [])
      .addThen((resp) => {
        setText("done!");
      })
      .addCatch((error) => {
        console.log(error);
      })
      .call();
    return () => {
      abort();
    };
  }, [setText]);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
sotobry profile image
Bryann Sotomayor-Rinaldi

Wow, you're brilliant!