Skip to content

Commit 3058bb3

Browse files
authored
fix: accept synchronous Queue.run callbacks (#516)
1 parent 8de6ffc commit 3058bb3

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

‎src/index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ export class Queue<T = unknown> {
167167
* @param {number} [priority=0] Optional priority, -1 is higher priority than 1
168168
* @return {Promise<any>} Resolved when the task has finished with the return value of fn
169169
*/
170-
run<U>(job: () => Promise<U>, priority?: number): Promise<U> {
170+
run<U>(job: () => U | PromiseLike<U>, priority?: number): Promise<U> {
171171
const prio = priority ?? 0;
172172
const id = Symbol();
173173
return this.wait(id as T, prio)

‎test/ts.test.ts‎

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,61 @@ describe('TS import', () => {
2929
const t: Promise<symbol> = q.run(() => Promise.resolve(Symbol()), 12);
3030
assert.instanceOf(t, Promise<symbol>);
3131
});
32+
33+
it('infers synchronous job results', async () => {
34+
const q = new Queue();
35+
const value = Symbol();
36+
const result: Promise<symbol> = q.run(() => value);
37+
assert.strictEqual(await result, value);
38+
await q.flush();
39+
assert.strictEqual(q.stat().running, 0);
40+
});
41+
42+
it('accepts synchronous jobs without a return value', async () => {
43+
const q = new Queue();
44+
let ran = false;
45+
const result: Promise<void> = q.run(() => {
46+
ran = true;
47+
});
48+
assert.isUndefined(await result);
49+
assert.isTrue(ran);
50+
await q.flush();
51+
});
52+
53+
it('infers jobs returning either values or promises', async () => {
54+
const q = new Queue();
55+
const job = (asynchronous: boolean): number | Promise<number> =>
56+
asynchronous ? Promise.resolve(42) : 42;
57+
const synchronous: Promise<number> = q.run(() => job(false));
58+
const asynchronous: Promise<number> = q.run(() => job(true));
59+
assert.strictEqual(await synchronous, 42);
60+
assert.strictEqual(await asynchronous, 42);
61+
await q.flush();
62+
});
63+
64+
it('accepts promise like job results', async () => {
65+
const q = new Queue();
66+
const thenable: PromiseLike<number> = {
67+
then: (onfulfilled, onrejected) => Promise.resolve(42).then(onfulfilled, onrejected)
68+
};
69+
const result: Promise<number> = q.run(() => thenable);
70+
assert.strictEqual(await result, 42);
71+
await q.flush();
72+
});
73+
74+
it('releases capacity after a synchronous job throws', async () => {
75+
const q = new Queue();
76+
const error = new Error('job failed');
77+
const failed: Promise<never> = q.run(() => {
78+
throw error;
79+
});
80+
const next: Promise<string> = q.run(() => 'next');
81+
await failed.then(
82+
() => assert.fail('expected job rejection'),
83+
(actual: Error) => assert.strictEqual(actual, error)
84+
);
85+
assert.strictEqual(await next, 'next');
86+
await q.flush();
87+
assert.strictEqual(q.stat().running, 0);
88+
});
3289
});

0 commit comments

Comments
 (0)