Skip to content

async-hooks: Is that possible to expose PromiseHooks resolve callback? #14038

Description

@JiaLiPassion

I am still working on porting zone.js with async_hooks. currently when I porting Promise, I met a problem and I think I need the resolve hook to be exposed.

case1: promise's parent is an resolved promise.

const p1 = Promise.resolve();

const p2 = p1.then(r => r);

In this case, current async_hooks API is ok, I can just schedule a microTask in zone.js in the init callback.

function init(id: number, provider: string, triggerId: number, parentHandle: any) {
    if (provider === PROMISE_PROVIDER) {
      if (!parentHandle) {
        return;
      }
      const parentId = parentHandle.parentId;
      if (!parentId) {
        return;
      }

      const task = Zone.current.scheduleMicroTask(PROMISE_SOURCE, noop, null, noop);
      promiseTasks[id] = task;
    }
  }

case2: the promise's parent is an unresolved promise.

const p1 = new Promise((resolve, reject) => {
    setTimeout(resolve, 3000);
});

const p2 = p1.then(r => r);

In this case, the microTask should not be scheduled in init, when the p1.then is called, because p1 is still unresolved, the microtask should be scheduled when p1.resolve is
called, so I wonder is that possible to expose the PromiseHook.resolve callback through async_hooks?

Thank you very much!

Activity

  1. addaleax commented on Jul 2, 2017

    @addaleax
    Member

    Yes, it would be possible to expose PromiseHook.resolve in some way, some people have been propising ideas for that. The easiest way would be to “just” add an extra hook just for the resolve event.

    Just mentioning one thing that was really confusing me:

    const p1 = new Promise(() => {}); // This will never be resolved
    const p2 = new Promise((resolve) => setTimeout(resolve, 1000, p1)); // resolve p2 with p1 after 1s

    p2 will still remain a pending promise, but the resolve promise hook will be called after 1 second, when resolve() is called. I hope that’s the behaviour you are looking for.

  2. added
    async_hooksIssues and PRs related to the async hooks subsystem.
    promisesIssues and PRs related to ECMAScript promises.
    on Jul 2, 2017
  3. JiaLiPassion commented on Jul 2, 2017

    @JiaLiPassion
    ContributorAuthor

    @addaleax , thank you for reply and point out the case.

    const p2 = new Promise((resolve) => setTimeout(resolve, 1000, p1)); // resolve p2 with p1 after 1s

    yeah, in this case, if resolve promise hook is called, I still don't know whether I should schedule a microtask or not.

    And in my understanding, this is the same with

    const p1 = {
      then() {
        // do something.
      }
    };
    const p2 = new Promise((resolve) => setTimeout(resolve, 1000, p1)); // resolve p2 with p1 after 1s

    resolve a promise with thenable will also leave this promise in pending state, so I realized that I need both resolve promise hook and a way to check promise state is resolved, pending or rejected. I am not sure is that possible to get those internal state information from v8.

  4. addaleax commented on Jul 2, 2017

    @addaleax
    Member

    so I realized that I need both resolve promise hook and a way to check promise state is resolved, pending or rejected. I am not sure is that possible to get those internal state information from v8.

    It is, at least through C++ API and undocumented internal Node APIs (process.binding('util').getPromiseDetails). I guess if you want to know when a Promise is resolved, you could add a .then() handler, but that’s going to come with problems of its own…

  5. JiaLiPassion commented on Jul 2, 2017

    @JiaLiPassion
    ContributorAuthor

    @addaleax , process.binding('util').getPromiseDetails, thank you!

    I guess if you want to know when a Promise is resolved, you could add a .then() handler, but that’s going to come with problems of its own…

    yes, if possible , I think in my case zone.js is just a wrapper, it should not add .then for every promise, so it will be better to resolve the issue with hook api.

  6. addaleax commented on Jul 2, 2017

    @addaleax
    Member

    @JiaLiPassion As I mentioned, it’s internal, and you should not rely on it; it can be removed or broken at any time.

  7. JiaLiPassion commented on Jul 2, 2017

    @JiaLiPassion
    ContributorAuthor

    @addaleax , got it! I will try to find out is there any other way to know when the promise is really resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    async_hooksIssues and PRs related to the async hooks subsystem.promisesIssues and PRs related to ECMAScript promises.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions