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

The spec lacks definition around the order of callbacks in nested promises #92

Closed
Mossop opened this issue Mar 28, 2013 · 6 comments
Closed

Comments

@Mossop
Copy link

Mossop commented Mar 28, 2013

Take this example:

function a() {}
function b() {}
function c() {}

var newPromise = promise.then(a);
newPromise.then(b);
promise.then(c);

If a() returns a promise that is not yet fulfilled then should c still be called immediately or should it be called after newPromise is fulfilled?

@domenic
Copy link
Member

domenic commented Mar 28, 2013

c should definitely be called immediately after a. I think this is covered fairly clearly by:

it must be called after promise is fulfilled, with promise's fulfillment value as its first argument.

If/when promise is fulfilled, all respective onFulfilled callbacks must execute in the order of their originating calls to then.

Since promise is fulfilled, a and c must both be called.

Technically we don't place any time limit on when you call them though... Hmm. "must execute immediately?" @briancavalier?


This is definitely a good case to add to the test suite, though! So we'll do that!

@Mossop
Copy link
Author

Mossop commented Mar 28, 2013

Does that imply that a and c should be called synchronously, i.e. there should be no event loop tick between the calls for them?

@briancavalier
Copy link
Member

The guarantees here are: a before b, and a before c. I don't know that we want to try to tighten down the timing any more than that. It seems reasonable to me that an implementation may choose to be computationally aggressive and call c as quickly as possible after a, or to be as IO/event-loop friendly as possible and defer c for another event-loop turn. As long as the guarantees above hold, both are valid.

I'm not really sure what language we could add that would cover that kind of variation any better than what we have now. I do see the point, though, that an implementation that waits a really long time between calling a and c probably isn't broadly useful :)

Kind of interesting, though, since in some systems, you might actually choose a promise implementation based on how it interacts with the event loop.

@Mossop
Copy link
Author

Mossop commented Mar 29, 2013

The guarantees here are: a before b, and a before c

Maybe just me but even saying that is very useful for clearing it up.

Kind of interesting, though, since in some systems, you might actually choose a promise implementation based on how it interacts with the event loop.

Yeah we're in the process of doing exactly that. In some cases we actually need totally synchronous behaviour (though those are largely shoehorning in promises for API stability and consistency reasons) and in others we want to force as much asynchronousness as possible

@briancavalier
Copy link
Member

Maybe just me but even saying that is very useful for clearing it up.

Cool, glad that helped. I'll give credit to @lsmith who said something similar over in #77, which you may find to be an interesting read as well, although it deals specifically with order, and not timing.

In some cases we actually need totally synchronous behaviour

Just make sure to be extra careful :) Relying on any synchronous behavior between promise callbacks can create refactoring hazards.

Is there anything else you feel we need to discuss for this issue? If not, please close.

@wizardwerdna
Copy link

I think the sequencing can be well-determined by the requirement that then must return before any callbacks are called. As a result (in javascript), the entire line of code will be executed by any callbacks until execution returns to C++ (in the case of nextTick in 0.10.x Node) or the next pass of the event loop.

For this reason, I think you can at most specify that the events are queued and run in sequence. "Immediate" here means queued for execution in an imminently future turn, but that seems dangerously beyond the scope of the specification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants