-
Notifications
You must be signed in to change notification settings - Fork 46
Unexpected execution order with multiple parents #158
Comments
Thanks for the very clear example here, this is effectively a "short-circuiting" behaviour of the execution ordering in the fulfillment handlers, and I can appreciate that it could seem an unintuitive deviation from the concept of the post-ordering. It's unclear if there is scope to make such a change at this stage, but if there was enough implementer concensus it could still be possible. I've posted an approach for applying this invariant in #159, which should achieve the behaviour you are looking for here. |
I found another case where the behavior is questionable. This time I tend more towards this being a v8 bug, but maybe you could help to confirm this. It's related to circular dependencies between c1 and c2: // async.mjs
console.log("async before");
await 0;
console.log("async after");
// c1.mjs
import "./c2.mjs";
import "./async.mjs";
console.log("c1");
// c2.mjs
import "./c1.mjs";
console.log("c2");
// x.mjs
import "./c2.mjs";
console.log("x");
// index.mjs
import "./c1.mjs";
import "./x.mjs";
console.log("index");
Intuitively expected output:
v8:
Note: This only happens when |
Also tested with on SpiderMonkey, which leads to yet another result:
|
@sokra in the above, the v8 output is correct per the spec while the SpiderMonkey output is a bug. The reason the exeuction happens this way is because async executions do not stop parallel execution of further dependencies in order not to be blocking - the async exec is started, then the algorithm moves on to execute the next post-order module that it can. |
hmm... I would see c1+c2+async as strongly connected component, so
There is also this note in the spec text:
|
Ah sorry I missed that c1 and c2 were in a cycle here, yes in that case, x should only execute after both c1 and c2 per the spec since attachment to async completions on the already-visited graph is based on GetCycleRoot. (so yes this is a v8 bug!) |
I think it would be benefical to include these two test cases or very similar in test-262, and leave this issue open to track that, regardless of the outcome of #159. |
While trying to ensure consistency between webpack's and v8 implementation I stumbled over this case:
Without the TLA this will behave as:
and since every module depends on the completion of the TLA, I would expect it to have the same output. The remaining graph would just execute sync after the await has finished. And I implemented it this way in webpack.
But to my surprise v8 doesn't behave this way. Instead it behaves like this:
So the question is who is right? I tried to read the spec and to me it seem like the spec also thinks that this is the spec'ed behavior. Am I reading the spec correctly? Is this is intended behavior? I also thought the remaining graph would execute in the same order as sync execution when there is no TLA in between. Is this a bug in the spec?
The text was updated successfully, but these errors were encountered: