Skip to content

Commit 18d330b

Browse files
authored
fix: deal with fast consecutive promise resolutions when streaming (#9332)
* fix: deal with fast consecutive promise resolutions when streaming fixes #9330 * Update packages/kit/src/utils/streaming.js
1 parent 620f560 commit 18d330b

File tree

3 files changed

+37
-5
lines changed

3 files changed

+37
-5
lines changed

.changeset/strange-garlics-pump.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
fix: deal with fast consecutive promise resolutions when streaming

packages/kit/src/utils/streaming.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,29 @@ function defer() {
2323
* }}
2424
*/
2525
export function create_async_iterator() {
26-
let deferred = defer();
26+
let deferred = [defer()];
2727

2828
return {
2929
iterator: {
3030
[Symbol.asyncIterator]() {
3131
return {
32-
next: () => deferred.promise
32+
next: async () => {
33+
const next = await deferred[0].promise;
34+
if (!next.done) deferred.shift();
35+
return next;
36+
}
3337
};
3438
}
3539
},
3640
push: (value) => {
37-
deferred.fulfil({ value, done: false });
38-
deferred = defer();
41+
deferred[deferred.length - 1].fulfil({
42+
value,
43+
done: false
44+
});
45+
deferred.push(defer());
3946
},
4047
done: () => {
41-
deferred.fulfil({ done: true });
48+
deferred[deferred.length - 1].fulfil({ done: true });
4249
}
4350
};
4451
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { test } from 'uvu';
2+
import * as assert from 'uvu/assert';
3+
import { create_async_iterator } from './streaming.js';
4+
5+
test(`works with fast consecutive promise resolutions`, async () => {
6+
const iterator = create_async_iterator();
7+
8+
Promise.resolve(1).then((n) => iterator.push(n));
9+
Promise.resolve(2).then((n) => iterator.push(n));
10+
Promise.resolve().then(() => iterator.done());
11+
12+
const actual = [];
13+
for await (const value of iterator.iterator) {
14+
actual.push(value);
15+
}
16+
17+
assert.equal(actual, [1, 2]);
18+
});
19+
20+
test.run();

0 commit comments

Comments
 (0)