1
1
'use strict' ;
2
2
3
3
const {
4
+ PromisePrototypeThen,
4
5
SymbolAsyncIterator,
5
6
SymbolIterator
6
7
} = primordials ;
@@ -42,9 +43,6 @@ function from(Readable, iterable, opts) {
42
43
// being called before last iteration completion.
43
44
let reading = false ;
44
45
45
- // Flag for when iterator needs to be explicitly closed.
46
- let needToClose = false ;
47
-
48
46
readable . _read = function ( ) {
49
47
if ( ! reading ) {
50
48
reading = true ;
@@ -53,18 +51,23 @@ function from(Readable, iterable, opts) {
53
51
} ;
54
52
55
53
readable . _destroy = function ( error , cb ) {
56
- if ( needToClose ) {
57
- needToClose = false ;
58
- close ( ) . then (
59
- ( ) => process . nextTick ( cb , error ) ,
60
- ( e ) => process . nextTick ( cb , error || e ) ,
61
- ) ;
62
- } else {
63
- cb ( error ) ;
64
- }
54
+ PromisePrototypeThen (
55
+ close ( error ) ,
56
+ ( ) => process . nextTick ( cb , error ) , // nextTick is here in case cb throws
57
+ ( e ) => process . nextTick ( cb , e || error ) ,
58
+ ) ;
65
59
} ;
66
60
67
- async function close ( ) {
61
+ async function close ( error ) {
62
+ const hadError = ( error !== undefined ) && ( error !== null ) ;
63
+ const hasThrow = typeof iterator . throw === 'function' ;
64
+ if ( hadError && hasThrow ) {
65
+ const { value, done } = await iterator . throw ( error ) ;
66
+ await value ;
67
+ if ( done ) {
68
+ return ;
69
+ }
70
+ }
68
71
if ( typeof iterator . return === 'function' ) {
69
72
const { value } = await iterator . return ( ) ;
70
73
await value ;
@@ -73,13 +76,9 @@ function from(Readable, iterable, opts) {
73
76
74
77
async function next ( ) {
75
78
try {
76
- needToClose = false ;
77
79
const { value, done } = await iterator . next ( ) ;
78
- needToClose = ! done ;
79
80
if ( done ) {
80
81
readable . push ( null ) ;
81
- } else if ( readable . destroyed ) {
82
- await close ( ) ;
83
82
} else {
84
83
const res = await value ;
85
84
if ( res === null ) {
0 commit comments