| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
There was a problem hiding this comment.
Good spot. I'm not sure needToClose is required, just always call return() in _destroy(). Also, please add a test.
Sorry, something went wrong.
There was a problem hiding this comment.
Would you mind to add a unit test for this? Thanks
Sorry, something went wrong.
Sorry, something went wrong.
for-of loop does this check. Why we shouldn't? |
Sorry, something went wrong.
|
Here is a "desugared" pseudo version of for-of I got from Gus Caplan: const iterator = B[Symbol.asyncIterator]();
while (true) {
const next = await iterator.next();
if (next.done) {
break;
}
const A = next.value;
// pseudocode follows, because dealing with `break` and `throw` is difficult to desugar.
const result = BODY;
if (result is a break or result is a throw) {
if (iterator.return !== undefined) {
let innerResult = iterator.return();
if (innerResult is not a throw) {
// if iterator.return() threw an exception, we don't want to await it.
innerResult = await innerResult;
}
if (result is a throw) {
// if BODY threw an exception, we want to throw that one instead of the possible
// exception from iterator.return()
throw result;
}
if (innerResult is a throw) {
// if iterator.return() threw, either directly or because it returned a rejected promise,
// now we re-throw that exception.
throw innerResult;
}
break;
}
}
}
I think that's probably what we should aim for. As you've noticed the throw + return() part is tricky. |
Sorry, something went wrong.
Where do you see this? Maybe? |
Sorry, something went wrong.
|
I'm sorry, it's quite difficult for me to understand that pseudocode. // next returns ordinary value, done = false:
for(const x of {
[Symbol.iterator](){ return this },
next(){ console.log('next'); return { value: 42, done: false } },
return(){ console.log('return'); return { done: true } }
}) {
console.log(x)
break
}
// output:
// next
// 42
// return
// undefined
// next returns done = true:
for(const x of {
[Symbol.iterator](){ return this },
next(){ console.log('next'); return { value: 42, done: true } },
return(){ console.log('return'); return { done: true } }
}) {
console.log(x)
break
}
// output:
// next
// undefined
// next throws
for(const x of {
[Symbol.iterator](){ return this },
next(){ console.log('next'); throw 42 },
return(){ console.log('return'); return { done: true } }
}) {
console.log(x)
break
}
// output:
// next
// Uncaught 42It seems that return isn't called if next throws. |
Sorry, something went wrong.
What do you want to illustrate with this?
Yes, that's what we are fixing in this PR? |
Sorry, something went wrong.
I mean
|
Sorry, something went wrong.
|
Ah, I think I understand what you mean. |
Sorry, something went wrong.
|
What happens if you do the same thing with async iterators? |
Sorry, something went wrong.
But then the problem with #32842 remains? I think looking at the for await..of would be relevant. |
Sorry, something went wrong.
Same thing happens if we use for-await-of with async iterator. |
Sorry, something went wrong.
We still need to deal with buffer in readable stream. |
Sorry, something went wrong.
There was a problem hiding this comment.
LGTM once tests are added, good job!
Sorry, something went wrong.
|
I'll write the tests, though it can take some time cause I'm gonna cover all these mentioned edge cases. |
Sorry, something went wrong.
|
Also, please take a look at the commit guidelines. You should use stream: as subsystem, and Fixes: before the url for the issue it fixed. |
Sorry, something went wrong.
|
Sure, I'll squash my draft commits into one when the job is done. |
Sorry, something went wrong.
|
I've added tests and it's allowed me to catch one more case. |
Sorry, something went wrong.
|
Actually the code does not look simpler) and the tests should remain in any case. |
Sorry, something went wrong.
There was a problem hiding this comment.
LGTM
Sorry, something went wrong.
Sorry, something went wrong.
There was a problem hiding this comment.
lgtm
Sorry, something went wrong.
Sorry, something went wrong.
|
@ronag @mcollina Btw, actually the code didn't contain any iterator.return() call, so it didn't close the iterator when not of its values were consumed. E.g. when the stream is destroyed. I guess this bugfix could be applied to node@12. Does it make sense? |
Sorry, something went wrong.
|
Absolutely, in due time. It will be included in the closest release of 12.x after 2 weeks of being in 13.x. |
Sorry, something went wrong.
|
Hi, I don't understand why needToClose is here? If someone destroys the stream we need to always close the generator don't we? |
Sorry, something went wrong.
|
That is - if someone creates a stream, calls .read but .next is never called on the generator - needToClose is false and blocks don't run (since await iterator.next()` is async and waits a microtick) |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Checklist
closes #32842