Wednesday, 7 November 2018

Constructor of a custom promise class is called twice (extending standard Promise)

I'm playing with Promise Extensions for JavaScript (prex) and I want to extend the standard Promise class with cancellation support using prex.CancellationToken, complete code here.

Unexpectedly, I'm seeing the constructor of my custom class CancellablePromise being called twice. To simplify things, I've now stripped down all the cancellation logic and left just a bare minimum required to repro the issue:

class CancellablePromise extends Promise {
  constructor(executor) {
    console.log("CancellablePromise::constructor");
    super(executor);
  }
}

function delayWithCancellation(timeoutMs, token) {
  // TODO: we've stripped all cancellation logic for now
  console.log("delayWithCancellation");
  return new CancellablePromise(resolve => {
    setTimeout(resolve, timeoutMs);
  }, token);
}

async function main() {
  await delayWithCancellation(2000, null);
  console.log("successfully delayed.");
}

main().catch(e => console.log(e));

Running it with node simple-test.js, I'm getting this:

delayWithCancellation
CancellablePromise::constructor
CancellablePromise::constructor
successfully delayed.

Why are there two invocations of CancellablePromise::constructor?

I tried setting breakpoints with VSCode. The stack trace for the second hit shows it's called from runMicrotasks, which itself is called from _tickCallback somewhere inside Node.



from Constructor of a custom promise class is called twice (extending standard Promise)

No comments:

Post a Comment