Skip to content

Commit aa9e597

Browse files
committed
Merge branch 'fn/better-promise-buffer' into fn/promise-try
2 parents e123946 + d8d6dec commit aa9e597

File tree

2 files changed

+61
-14
lines changed

2 files changed

+61
-14
lines changed

packages/core/src/utils/promisebuffer.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,6 @@ export function makePromiseBuffer<T>(limit: number = 100): PromiseBuffer<T> {
5656
return task;
5757
}
5858

59-
function drainNextSyncPromise(): PromiseLike<boolean> {
60-
const item = buffer.values().next().value;
61-
62-
if (!item) {
63-
return resolvedSyncPromise(true);
64-
}
65-
66-
return resolvedSyncPromise(item).then(() => {
67-
return drainNextSyncPromise();
68-
});
69-
}
70-
7159
/**
7260
* Wait for all promises in the queue to resolve or for timeout to expire, whichever comes first.
7361
*
@@ -82,7 +70,7 @@ export function makePromiseBuffer<T>(limit: number = 100): PromiseBuffer<T> {
8270
return resolvedSyncPromise(true);
8371
}
8472

85-
const drainPromise = drainNextSyncPromise();
73+
const drainPromise = Promise.all(Array.from(buffer)).then(() => true);
8674

8775
if (!timeout) {
8876
return drainPromise;

packages/core/test/lib/utils/promisebuffer.test.ts

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,44 @@ import { rejectedSyncPromise, resolvedSyncPromise } from '../../../src/utils/syn
44

55
describe('PromiseBuffer', () => {
66
describe('add()', () => {
7+
test('enforces limit of promises', async () => {
8+
const buffer = makePromiseBuffer(5);
9+
10+
const producer1 = vi.fn(() => new Promise(resolve => setTimeout(resolve, 1)));
11+
const producer2 = vi.fn(() => new Promise(resolve => setTimeout(resolve, 1)));
12+
const producer3 = vi.fn(() => new Promise(resolve => setTimeout(resolve, 1)));
13+
const producer4 = vi.fn(() => new Promise(resolve => setTimeout(resolve, 1)));
14+
const producer5 = vi.fn(() => new Promise(resolve => setTimeout(resolve, 1)));
15+
const producer6 = vi.fn(() => new Promise(resolve => setTimeout(resolve, 1)));
16+
17+
void buffer.add(producer1);
18+
void buffer.add(producer2);
19+
void buffer.add(producer3);
20+
void buffer.add(producer4);
21+
void buffer.add(producer5);
22+
void expect(buffer.add(producer6)).rejects.toThrowError();
23+
24+
expect(producer1).toHaveBeenCalledTimes(1);
25+
expect(producer2).toHaveBeenCalledTimes(1);
26+
expect(producer3).toHaveBeenCalledTimes(1);
27+
expect(producer4).toHaveBeenCalledTimes(1);
28+
expect(producer5).toHaveBeenCalledTimes(1);
29+
expect(producer6).not.toHaveBeenCalled();
30+
31+
expect(buffer.$.length).toEqual(5);
32+
33+
await buffer.drain();
34+
35+
expect(buffer.$.length).toEqual(0);
36+
37+
expect(producer1).toHaveBeenCalledTimes(1);
38+
expect(producer2).toHaveBeenCalledTimes(1);
39+
expect(producer3).toHaveBeenCalledTimes(1);
40+
expect(producer4).toHaveBeenCalledTimes(1);
41+
expect(producer5).toHaveBeenCalledTimes(1);
42+
expect(producer6).not.toHaveBeenCalled();
43+
});
44+
745
test('sync promises', () => {
846
const buffer = makePromiseBuffer(1);
947
let task1;
@@ -34,6 +72,27 @@ describe('PromiseBuffer', () => {
3472
expect(producer1).toHaveBeenCalled();
3573
expect(producer2).not.toHaveBeenCalled();
3674
});
75+
76+
test('handles multiple equivalent promises', async () => {
77+
const buffer = makePromiseBuffer(10);
78+
79+
const promise = new Promise(resolve => setTimeout(resolve, 1));
80+
81+
const producer = vi.fn(() => promise);
82+
const producer2 = vi.fn(() => promise);
83+
84+
expect(buffer.add(producer)).toEqual(promise);
85+
expect(buffer.add(producer2)).toEqual(promise);
86+
87+
expect(buffer.$.length).toEqual(1);
88+
89+
expect(producer).toHaveBeenCalled();
90+
expect(producer2).toHaveBeenCalled();
91+
92+
await buffer.drain();
93+
94+
expect(buffer.$.length).toEqual(0);
95+
});
3796
});
3897

3998
describe('drain()', () => {
@@ -62,7 +121,7 @@ describe('PromiseBuffer', () => {
62121
expect(p5).toHaveBeenCalled();
63122
});
64123

65-
test('drains all promises with timeout xxx', async () => {
124+
test('drains all promises with timeout', async () => {
66125
const buffer = makePromiseBuffer();
67126

68127
const p1 = vi.fn(() => new Promise(resolve => setTimeout(resolve, 2)));

0 commit comments

Comments
 (0)