Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
JiaLiPassion opened this issue Jul 2, 2017 · 6 comments
Closed
Labels
async_hooks Issues and PRs related to the async hooks subsystem. promises Issues and PRs related to ECMAScript promises.

Comments

@JiaLiPassion
Copy link
Contributor

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!

@addaleax
Copy link
Member

addaleax commented Jul 2, 2017

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.

@addaleax addaleax added async_hooks Issues and PRs related to the async hooks subsystem. promises Issues and PRs related to ECMAScript promises. labels Jul 2, 2017
@JiaLiPassion
Copy link
Contributor Author

@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.

@addaleax
Copy link
Member

addaleax commented Jul 2, 2017

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…

@JiaLiPassion
Copy link
Contributor Author

@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.

@addaleax
Copy link
Member

addaleax commented Jul 2, 2017

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

@JiaLiPassion
Copy link
Contributor Author

@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
Labels
async_hooks Issues and PRs related to the async hooks subsystem. promises Issues and PRs related to ECMAScript promises.
Projects
None yet
Development

No branches or pull requests

2 participants