Skip to content

Commit d25262e

Browse files
Correctly delegate .return() in async generator (#10422)
* Correctly delegate .return() in async generator * Add catch param * minNodeVersion * Add another test
1 parent 8618447 commit d25262e

17 files changed

Lines changed: 264 additions & 5 deletions

File tree

packages/babel-helpers/src/helpers.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ helpers.AsyncGenerator = helper("7.0.0-beta.0")`
136136
Promise.resolve(wrappedAwait ? value.wrapped : value).then(
137137
function (arg) {
138138
if (wrappedAwait) {
139-
resume("next", arg);
139+
resume(key === "return" ? "return" : "next", arg);
140140
return
141141
}
142142
@@ -238,6 +238,10 @@ helpers.asyncGeneratorDelegate = helper("7.0.0-beta.0")`
238238
239239
if (typeof inner.return === "function") {
240240
iter.return = function (value) {
241+
if (waiting) {
242+
waiting = false;
243+
return value;
244+
}
241245
return pump("return", value);
242246
};
243247
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
const log = [];
2+
3+
async function* func1() {
4+
log.push(1);
5+
yield "a";
6+
log.push(2);
7+
}
8+
9+
async function* func2() {
10+
yield* func1();
11+
log.push(3);
12+
}
13+
14+
return (async () => {
15+
const iterator = func2();
16+
await iterator.next();
17+
await iterator.return();
18+
19+
expect(log).toEqual([1]);
20+
})();
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"minNodeVersion": "8.0.0"
3+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"parserOpts": {
3+
"allowReturnOutsideFunction": true
4+
},
5+
"plugins": [
6+
"external-helpers",
7+
"transform-async-to-generator",
8+
"proposal-async-generator-functions"
9+
]
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
const log = [];
2+
3+
async function* inner() {
4+
try {
5+
log.push(1);
6+
yield "a";
7+
log.push(2);
8+
yield "b";
9+
log.push(3);
10+
} finally {
11+
log.push(4);
12+
yield "c";
13+
log.push(5);
14+
}
15+
}
16+
17+
async function* outer() {
18+
log.push(6);
19+
yield* inner();
20+
log.push(7);
21+
}
22+
23+
return (async () => {
24+
const iterator = outer();
25+
26+
let res = await iterator.next();
27+
expect(res).toEqual({ value: "a", done: false });
28+
expect(log).toEqual([6, 1]);
29+
30+
const [res1, res2] = await Promise.all([ iterator.return("x"), iterator.return("y") ]);
31+
expect(res1).toEqual({ value: "c", done: false });
32+
expect(res2).toEqual({ value: "y", done: true });
33+
expect(log).toEqual([6, 1, 4]);
34+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"minNodeVersion": "8.0.0"
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
const log = [];
2+
3+
async function* inner() {
4+
try {
5+
log.push(1);
6+
yield "a";
7+
log.push(2);
8+
yield "b";
9+
log.push(3);
10+
} finally {
11+
log.push(4);
12+
yield "c";
13+
log.push(5);
14+
}
15+
}
16+
17+
async function* outer() {
18+
log.push(6);
19+
yield* inner();
20+
log.push(7);
21+
}
22+
23+
return (async () => {
24+
const iterator = outer();
25+
26+
let res = await iterator.next();
27+
expect(res).toEqual({ value: "a", done: false });
28+
expect(log).toEqual([6, 1]);
29+
30+
res = await iterator.return("x");
31+
expect(res).toEqual({ value: "c", done: false });
32+
expect(log).toEqual([6, 1, 4]);
33+
34+
res = await iterator.return("y");
35+
expect(res).toEqual({ value: "y", done: true });
36+
expect(log).toEqual([6, 1, 4]);
37+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"minNodeVersion": "8.0.0"
3+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
const log = [];
2+
3+
async function* inner() {
4+
try {
5+
log.push(1);
6+
yield "a";
7+
log.push(2);
8+
yield "b";
9+
log.push(3);
10+
} finally {
11+
log.push(4);
12+
yield "c";
13+
log.push(5);
14+
}
15+
}
16+
17+
async function* outer() {
18+
log.push(6);
19+
yield* inner();
20+
log.push(7);
21+
}
22+
23+
return (async () => {
24+
const iterator = outer();
25+
26+
let res = await iterator.next();
27+
expect(res).toEqual({ value: "a", done: false });
28+
expect(log).toEqual([6, 1]);
29+
30+
res = await iterator.return();
31+
expect(res).toEqual({ value: "c", done: false });
32+
expect(log).toEqual([6, 1, 4]);
33+
34+
res = await iterator.next();
35+
expect(res).toEqual({ value: undefined, done: true });
36+
expect(log).toEqual([6, 1, 4, 5, 7]);
37+
})();
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
const log = [];
2+
3+
async function* inner() {
4+
log.push(1);
5+
yield "a";
6+
log.push(2);
7+
yield "b";
8+
log.push(3);
9+
}
10+
11+
async function* outer() {
12+
log.push(4);
13+
yield* inner();
14+
log.push(5);
15+
}
16+
17+
return (async () => {
18+
const iterator = outer();
19+
20+
let res = await iterator.next();
21+
expect(res).toEqual({ value: "a", done: false });
22+
expect(log).toEqual([4, 1]);
23+
24+
res = await iterator.return();
25+
expect(res).toEqual({ value: undefined, done: true });
26+
expect(log).toEqual([4, 1]);
27+
28+
res = await iterator.next();
29+
expect(res).toEqual({ value: undefined, done: true });
30+
expect(log).toEqual([4, 1]);
31+
})();

0 commit comments

Comments
 (0)