Open Bug 1680059 Opened 5 years ago Updated 4 years ago

Add a function that makes it safe to pass Promises from globals that may go away before the promise settles.

Categories

(Toolkit :: Async Tooling, enhancement)

enhancement

Tracking

()

People

(Reporter: mossop, Unassigned)

References

Details

When a global such as a window is destroyed any promises created from that global that have not yet settled will never call their handlers regardless of whether they subsequently settle or not. This means passing a promise from a window to a JSM could potentially cause something similar to a deadlock where that promise never settles and so the JSM gets stuck waiting for something that will never happen.

A way to wallpaper over this would be to add a wrapping function that safely rejects a promise if its global window goes away:

function wrapWindowPromise(promise) {
  let window = Cu.getGlobalForObject(promise);
  if (!(window instanceof Ci.nsIDOMWindow)) {
    return promise;
  }

  return new Promise((resolve, reject) => {
    let listener = () => {
      reject(new Error("Window has closed."));
    };

    window.addEventListener("close", listener);
    promise
      .then(resolve, reject)
      .finally(() => window.removeEventListener("close", listener));
  });
}

As long as this function is in a global that never dies, such as a JSM the returned promise will reject when the window dies.

See Also: → 1674505
You need to log in before you can comment on or make changes to this bug.