transpile async promise
When target is ES5, allow an option to transpile async/await to Promises rather than switches. This would require Promises to be polyfilled, hence would be optional.
This was previously discussed on this issue but was closed with this comment by @mhegazy:
this may be true for code with small list of await expressions. but it does not scale for the general case. once you have a loop with an await expression, you can not use promises.
@mhegazy can you explain this? I have used fast-async to transpile loops to promises before. Is there some edge-case where it is not possible?
Current approach creates emitted code that cannot be source-mapped properly by some debuggers.
export const foo = async (): Promise<number> => await Promise.resolve(1) + 1;
Currently emits this:
exports.foo = function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, Promise.resolve(1)];
case 1: return [2 /*return*/, (_a.sent()) + 1];
}
}); }); };
Instead it should emit something like this (output from fast-async:
exports.foo = function foo() {
return new Promise(function ($return, $error) {
return Promise.resolve(1).then(function ($await_7) {
return $return($await_7 + 1);
}.$asyncbind(this, $error), $error);
});
};
Here's an example of fast-async transpiling a loop:
async function Foo() {
for (let x = 0; x < 5; x++) {
console.log("FOO: " + await Promise.resolve(x));
}
}
becomes
function Foo() {
return new Promise(function ($return, $error) {
var x;
x = 0;
function $Loop_4_step() {
x++;
return $Loop_4;
}
function $Loop_4() {
if (x < 5) {
return Promise.resolve(x).then(function ($await_6) {
console.log("FOO: " + $await_6);
return $Loop_4_step;
}.$asyncbind(this, $error), $error);
} else return [1];
}
return Function.$asyncbind.trampoline(this, $Loop_4_exit, $Loop_4_step, $error, true)($Loop_4);
function $Loop_4_exit() {
return $return();
}
});
}
Here's a while loop:
async function Foo() {
let x = 0;
while (x < 5) {
x += await Promise.resolve(1);
console.log("FOO: " + x);
}
}
transpiles to:
function Foo() {
return new Promise(function ($return, $error) {
var x;
x = 0;
function $Loop_4() {
if (x < 5) {
return Promise.resolve(1).then(function ($await_6) {
x += $await_6;
console.log("FOO: " + x);
return $Loop_4;
}.$asyncbind(this, $error), $error);
} else return [1];
}
return Function.$asyncbind.trampoline(this, $Loop_4_exit, $Loop_4, $error, true)($Loop_4);
function $Loop_4_exit() {
return $return();
}
});
}
+1 for this, would it be possible to integrate with fast-async?
that's true, the current implementation is virtually impossible to understand/debug in production code that is shipped without source maps but with Promises simply pretty print of any debugger is enough.
Still, lots of enterprise products support IE11 and it makes usage of async/await impossible for such projects until the whole team learns how _awaiter works and code transpiled to Promises would be great if possible.
Most helpful comment
+1 for this, would it be possible to integrate with fast-async?