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/await/Promise scheduling order wrong #31552
Comments
Does the spec require |
If my understanding about the event loop and microtask queue scheduling is correct, then yes, Typescript's behavior is wrong. My meager understanding is based on what I learned reading https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/. That article doesn't address async/await functions specifically, but I'm pretty sure |
The reason is that we don't depend on const p = Promise.resolve();
Promise.resolve(p).then(onfulfilled); // 1
new Promise(resolve => resolve(p)).then(onfulfilled); // 2 Both (1) and (2) perform state adoption of |
It seems this is because
Where |
I actually remember reading something about this somewhere, to the effect of:
...and these two cases, while they sound identical (in both cases you get the callback on the next tick), are actually subtly different. The JS promise semantics are really, really weird. |
Proposed change: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
}; |
I believe |
Yeah, |
TypeScript Version: 3.3, 3.5.0-dev.20190523
Search Terms: async await Promise order scheduling microtask
Code
Expected behavior: Log 1 then 2. Chrome and Node.js get this right. Babel's transpiled JS also gets it right.
Actual behavior: Logs 2 then 1.
Playground Link: https://www.typescriptlang.org/play/#src=async%20function%20a(msg)%20%7B%0D%0A%20%20await%20Promise.resolve()%3B%0D%0A%20%20console.log(msg)%3B%0D%0A%7D%0D%0A%0D%0Afunction%20b(msg)%20%7B%0D%0A%20%20Promise.resolve().then(()%20%3D%3E%20%7B%0D%0A%20%20%20%20console.log(msg)%3B%0D%0A%20%20%7D)%3B%0D%0A%7D%0D%0A%0D%0Aa('1')%3B%0D%0Ab('2')%3B%0D%0A
Babel Link: https://babeljs.io/repl/#?babili=false&browsers=&build=&builtIns=false&spec=false&loose=false&code_lz=IYZwngdgxgBAZgV2gFwJYHsI2ACgLYgDmAlDAN4BQM2A7sKsjAAoBO6eqIApgHQtch0AGwBuXHMQDcVGFEyChvIekL4iUigF8KFRCgxYARmpLkZrdp178FYiT2QALLhBwSYAXgB8Z6tTkQCkoqJhrUmhraFLgA5ACMMRrGMQBMidJAA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=true&fileSize=false&timeTravel=false&sourceType=script&lineWrap=true&presets=es2015%2Ces2017&prettier=false&targets=&version=7.4.5&externalPlugins=
Related Issues: Didn't find any.
The text was updated successfully, but these errors were encountered: