/HungIframePromise

Minimal repro of promises waiting on iframe code hanging after iframe is destroyed

Primary LanguageHTML

README

This simple repro demonstrates an unexpected "frozen-promise" behavior that occurs when code calls a long-running iframe function, and the iframe is destroyed before the function completes. See the live demo at https://zlatkovsky.github.io/HungIframePromise/

Our expectation is that if the "outside" window calls something on the iframe and gets a Promise returned, that Promise should either resolve or reject, but it shouldn't just hang indefinitely. If the iframe is destroyed and all code stops executing on the iframe -- which seems to be the case -- the Promise should reject with some sort of "Execution context is destroyed" error.

Host code:

try {
  console.log("Host App: Starting call to iframe function, this will take 2 seconds");
  await iframe.contentWindow.longRunningIframeFunction();
  console.log("Host App: Finished call to iframe function");
} catch (e) {
  console.error(`Host App: Caught error when executing iframe function. Error was: "${e}"`);
}
console.log("Host App: invokeSomethingOnIframe is done");

Iframe code:

window.longRunningIframeFunction = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log("Iframe: finished waiting 2 seconds, returning the Promise");
      resolve();
    }, 2000);
  });
};

In our production-app case, the hanging Promise causes cleanup code -- which would otherwise run as soon as the Promise is resolved or rejected -- to not run. This, in turn, causes a massive memory leak.

Running the code

To run the code, simply serve it using a web server. E.g.,:

npm install -g http-server
http-server

If you make changes, you will likely want to open F12 tools and do a "Empty cache and hard refresh"