Skip to content

Commit 0d672b5

Browse files
author
Nick Clark
committed
Ensure onClose is only called once we receive a value from the listener
1 parent 837379c commit 0d672b5

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

src/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,14 @@ function callbackToAsyncIterator<CallbackInput: any, ReturnVal: any>(
2121
let pushQueue = [];
2222
let listening = true;
2323
let listenerReturnValue;
24+
let listenerReturnedValue = false;
25+
let closingWaitingOnListenerReturnValue = false;
2426
// Start listener
2527
listener(value => pushValue(value))
2628
.then(a => {
2729
listenerReturnValue = a;
30+
listenerReturnedValue = true;
31+
if (closingWaitingOnListenerReturnValue) emptyQueue();
2832
})
2933
.catch(err => {
3034
onError(err);
@@ -49,6 +53,10 @@ function callbackToAsyncIterator<CallbackInput: any, ReturnVal: any>(
4953
}
5054

5155
function emptyQueue() {
56+
if (onClose && !listenerReturnedValue) {
57+
closingWaitingOnListenerReturnValue = true;
58+
return;
59+
}
5260
if (listening) {
5361
listening = false;
5462
pullQueue.forEach(resolve => resolve({ value: undefined, done: true }));

src/test/index.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,24 @@ describe('options', () => {
145145
await iter.return();
146146
});
147147

148+
it('should call onClose with the return value from an listener only after the promise resolves', async () => {
149+
const returnValue = 'asdf';
150+
const listener = (cb: () => void) =>
151+
new Promise(res => {
152+
res(returnValue);
153+
});
154+
155+
expect.hasAssertions();
156+
const iter = asyncify(listener, {
157+
onClose: val => {
158+
expect(val).toEqual(returnValue);
159+
},
160+
});
161+
// Wait a tick so that the promise resolves with the return value
162+
iter.return();
163+
await new Promise(res => setTimeout(res, 10));
164+
});
165+
148166
describe('buffering', () => {
149167
it('should not buffer incoming values if disabled', async () => {
150168
const listener = (cb: (arg: number) => void) =>

0 commit comments

Comments
 (0)