-
-
Notifications
You must be signed in to change notification settings - Fork 41
Additional .then call incorrectly inserted #21
Comments
Nice find, returns are tricky... If statements in particular are rewritten in all kinds of ways to try to prevent this kind of situation. Remove 1 or 2, and other code paths will be taken so that doesn't surprise me. Can I use your input sample as the base of a test suite test case? The underlying problem is that if statements, at least in some situations, are probably marked as 'dirty': that means, they can return other values than actual return values, e.g. when await-ing something. That's wrong: instead, if statement branches (the code inside if and else blocks) should be marked as possibly dirty, but not the whole thing. |
@marten-de-vries Hmm, if you convert an empty return to |
async function test() {
await a();
} -> function test() {
return Promise.resolve().then(function () {
return a();
}).then(function () {});
} So, no. Adding a return statement in that case is only more verbose. The problem is that the final part of the chain is added while it really shouldn't be for this issue. |
@marten-de-vries sure, use this example as you want. I tried to make it as simple as possible. I've got a lot of async code that needs to run on ES5 so when a new version of kneden is available I can thoroughly test it :) Currently I'm using fast-async but kneden's output looks a lot better. |
@marten-de-vries Thanks, make sense. |
Added failing test in 89f3a91. |
#43 contains a fix. Needs more testing, though. |
As a side-note, couldn't
By translated into
Instead? Or if you're worried about
Couldn't you? That would be a little more compact and legible than
IMO. |
To be spec compliant, the entire body of the |
Aha. Sorry for bothering you, I thought I saw an opportunity for improvement but I should have known better 😄 |
I forked this repo and did some tests locally. // 1. AwaitExpression
async function fnAwaitExpression(a){
if(!a) return;
await Promise.resolve(a);
}
// 2. AwaitExpression (transpiled)
function _fnAwaitExpression(a) {
return Promise.resolve().then(function () {
if (!!a) {
return Promise.resolve(a);
}
}).then(function () {});
}
// 3. ReturnExpression + AwaitExpression
async function fnReturnAwaitExpression(a){
if(!a) return;
return await Promise.resolve(a);
}
// 4. ReturnExpression + AwaitExpression (transpiled)
function _fnReturnAwaitExpression(a) {
return Promise.resolve()
.then(function () {
if (!!a) {
return Promise.resolve(a);
}
})
// We know this swallows the inner return.
// And we know this is added for the case of an AwaitExpression, @see 1. and 2.
.then(function () {});
}
fnAwaitExpression("a").then(v => {console.log(v)}); //=> nothing!
_fnAwaitExpression("a").then(v => {console.log(v)}); //=> nothing! Correct behavior.
fnReturnAwaitExpression("b").then(v => {console.log(v)}); //=> b
_fnReturnAwaitExpression("b").then(v => {console.log(v)}); //=> nothing! Wrong behavior. Expected b. In order to add the additional function _fnAwaitExpression(a) {
return Promise.resolve().then(function () {
if (!!a) {
return Promise.resolve(a)
+ .then(function () {});
}
})
- .then(function () {});
} So moving the function _fnAwaitExpression(a) {
return Promise.resolve().then(function () {
if (!!a) {
return Promise.resolve(a)
}
});
- .then(function () {});
}
_fnReturnAwaitExpression("b").then(v => {console.log(v)}); //=> b! Correct behavior.
|
@raphaelokon @marten-de-vries async function fnAwaitExpression(a){
if(!a) return;
const ret = await Promise.resolve(a);
return ret;
} result: function fnAwaitExpression(a) {
var ret;
return Promise.resolve().then(function () {
if (!!a) {
return Promise.resolve().then(function () {
return Promise.resolve(a);
}).then(function (_resp) {
ret = _resp;
return ret;
});
}
}).then(function () {});
} some times i should do something after |
I don't think this is resolved yet. |
Seeing |
That may be true, but that means that the issue should remain open forever, in case someone comes along later to maintain it. |
Hello,
I've encountered a case when kneden incorrectly adds extra
.then(function () {});
call at the end of the generated async function.Consider this code:
It produces the following code:
The last
.then
call swallows the lastreturn
statement. If you comment out line 1 or 2 then the generated code is correct (no extra.then
).I'm using:
require('babel-core').transform(source, { presets: "es2015", plugins: ["kneden"]}).code
with these dependencies:
Oh, by the way thanks for this awesome library! The generated code is perfectly readable.
The text was updated successfully, but these errors were encountered: