fix: replace setImmediate with a cross environment compatible version

This commit is contained in:
鲁树人 2023-05-18 22:00:43 +01:00
parent 604eb6f939
commit ab554b0470
3 changed files with 17 additions and 3 deletions

View File

@ -1,3 +1,5 @@
import { nextTickAsync } from './nextTick';
export abstract class ConcurrentQueue<T, R = unknown> { export abstract class ConcurrentQueue<T, R = unknown> {
protected items: [T, (result: R) => void, (error: unknown) => void][] = []; protected items: [T, (result: R) => void, (error: unknown) => void][] = [];
@ -37,7 +39,7 @@ export abstract class ConcurrentQueue<T, R = unknown> {
} catch (error: unknown) { } catch (error: unknown) {
reject(error); reject(error);
} finally { } finally {
await new Promise((resolve) => setImmediate(resolve)); await nextTickAsync();
} }
} }
} }

View File

@ -1,4 +1,5 @@
import { ConcurrentQueue } from '../ConcurrentQueue'; import { ConcurrentQueue } from '../ConcurrentQueue';
import { nextTickAsync } from '../nextTick';
class SimpleQueue<T, R = void> extends ConcurrentQueue<T> { class SimpleQueue<T, R = void> extends ConcurrentQueue<T> {
handler(_item: T): Promise<R> { handler(_item: T): Promise<R> {
@ -40,7 +41,7 @@ test('should be able to process the queue within limit', async () => {
// Wait till all fullfilled // Wait till all fullfilled
while (queuedResolver.length !== 5) { while (queuedResolver.length !== 5) {
await new Promise((resolve) => setImmediate(resolve)); await nextTickAsync();
} }
// Now it should've queued everything. // Now it should've queued everything.
@ -92,7 +93,7 @@ test('it should move on to the next item in the queue once failed', async () =>
// Wait till all fullfilled // Wait till all fullfilled
while (queuedResolver.length !== 4) { while (queuedResolver.length !== 4) {
await new Promise((resolve) => setImmediate(resolve)); await nextTickAsync();
} }
// Should've moved on, as 3 will throw error // Should've moved on, as 3 will throw error

11
src/util/nextTick.ts Normal file
View File

@ -0,0 +1,11 @@
type NextTickFn = (callback: () => void) => void;
const nextTickFn =
typeof setImmediate !== 'undefined'
? (setImmediate as NextTickFn)
: typeof requestAnimationFrame !== 'undefined'
? (requestAnimationFrame as NextTickFn)
: (setTimeout as NextTickFn);
export async function nextTickAsync() {
return new Promise<void>((resolve) => nextTickFn(resolve));
}