-
Notifications
You must be signed in to change notification settings - Fork 108
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
Sequencing of promise resolution not being tested #61
Comments
And another test case (which looks like it should be the same, but definitely isn't): T2a var resolveP1, rejectP2, p1, p2;
p1 = new Promise(function(resolve, reject) {
resolveP1 = resolve;
});
p2 = new Promise(function(resolve, reject) {
rejectP2 = reject;
});
rejectP2("B");
resolveP1("A");
p1.then(function(msg){
console.log(msg);
});
p2.catch(function(msg){
console.log(msg);
});
|
And a variation of the second test with different behavior. T2b: var resolveP1, rejectP2, p1, p2;
p1 = new Promise(function(resolve, reject) {
resolveP1 = resolve;
});
p2 = new Promise(function(resolve, reject) {
rejectP2 = reject;
});
rejectP2("B");
resolveP1("A");
setTimeout(function(){
p1.then(function(msg){
console.log(msg);
});
p2.catch(function(msg){
console.log(msg);
});
},0); Pretty clear this should print "A B", right? |
Actually, the more I think about it, the more I think T2a (without the timeout) should be "B A" and T2b (with the timeout) should be "A B". Here's my reasoning:
So the queue looks like: "rejectP2 -> resolveP1". For T2a, before that scheduling queue completes, both When that next cycle runs and processes the queue, With T2b (where the timeout defers the then/catch registration until the next cycle, sorta), the order of registering the Is that analysis correct for test cases T2a and T2b? |
The reference implementation prints "A B" for all three cases. I think what happens in To2A is:
The tests are rough right now, but I will polish them a bit and add them to the sequencer PR. |
The tests are now polished and can be run under mocha in the promises-unwrapping project, branch smikes:sequencer-test Link to the PR - domenic/promises-unwrapping#111 |
The two promises in the original post are completely independent. Promises/A+ doesn't make any attempt to lock down the order of that situation, and imho, it shouldn't. Developers shouldn't make any assumptions about invisible relationships between independent promises. If they did, then any nondeterminism or timing change due to refactoring upstream could break their code or cause subtle bugs. The point of The discussion over in promises-aplus/promises-spec#77 might be worth a read, even though the original case is slightly different. |
Brian, the problem with that perspective is that the order is observable with Promise.race |
Promise.race is not part of Promises/A+... |
well, the discussion of what expected semantics (for promise.race) is important even if a+ isn't the place where the test ends up. moreover, Promise.race isn't really exposing its own sequencing semantics, it's exposing a fundamental characteristic of the promise itself (how it puts stuff on the event queue). |
Ah, interesting point. It's outside of A+, as @domenic said, but you could raise the discussion on an ES6 Promise forum. |
IOW: we have to define the sequencing semantic somewhere, because diffs in implementation affecting how promise.race behaves are intolerable. But we can't define only what promise.race semantics are, because the side effects are observable even without race. Therefore, some body (either a+ or tc39) has to define how two promises sequence. |
It's already defined by TC39, in the ES6 spec. |
it should be |
I am here with this conversation because I already went to the ES6 spec and I did not find (it's quite possible I didn't know how to find what I was looking for) much of anything that suggests the proper sequencing semantic between independent promises (plenty said about sequencing within a promise), other than the language about "Tasks" and "Task queues". If my reasoning below is somehow wrong by what the spec already says, I would certainly appreciate being pointed to the specific sections. My understanding is that the calls to the If so, that means that the first Task in the queue is to disposition The next Task in the queue is to disposition Setting aside the discussion of Please help me understand what I'm missing that insists on "A B" as the proper result for T2a. |
Incorrect, it queues a task to call those handlers. See TriggerPromiseReactions in the spec. |
OK, but it still queues them in the "B A" order. Or... not? |
No; the handler for The reference implementation is made for exploring these kinds of things, BTW. Stepping through it in a debugger can give the clearest answers. |
For posterity and anyone who cares, I have tracked down (the hard way) what my misunderstanding was. The problem was I was thinking in T2a that Thus, the tasks enqueued (with respect to this situation) come only from the Hence, "A B". |
I have run across a bug (thanks to @smikes) in my native-promise-only promise polyfill that is not caught by the current promises/a+ test suite (which NPO already passes).
I just checked the open issues here, and the issue I've found may indeed be the same as, or related to, that reported in #59. However, my test case is expressed a little differently, so documenting here separately just in case they are two different things needing to be tested.
In particular, I have a latent bug in the internal scheduler of NPO (which I've already diagnosed and understand) that affects how the sequencing of two different promise
then(..)
handlers are fired compared to what would be expected.Here's the test case:
T1
According to my understanding of the spec, and according to v8, the print out should be "A B".
My unfixed library prints out "B A". When I correct my scheduler bug, I get "A B" as I would expect.
The problem, as stated above and in #59, is that NPO is already passing all 872 tests for its
then(..)
behavior, even with this sequencing bug, because the test suite is apparently not asserting anything about this expected sequencing (though it is clearly implied by the spec).What concerns me is that it seems like maybe this is more than just one test that's missing, but potentially a whole class of tests that make assertions about then-sequencing semantics between independent promises.
OTOH, perhaps the promises/a+ spec isn't specific enough about such inter-promise semantics, and maybe that accounts for the shortfall of tests.
The text was updated successfully, but these errors were encountered: