INTEGRITY Документация

Планировщик

Контекст

scheduler глобальный объект предоставляет API для планирования задач на основе предложение WICG Scheduling APIs. В настоящее время Workers реализует scheduler.wait() метод.

scheduler.wait() возвращает Promise, который выполняется через заданное количество миллисекунд. Это await-совместимая альтернатива setTimeout() который не требует callback-функции.

Подобно другим таймеры в Workers, scheduler.wait() не увеличивается во время выполнения CPU при развертывании в Cloudflare. Это мера безопасности для защиты от атак Spectre. При локальной разработке таймеры продолжают отсчёт независимо от того, происходит ли ввод-вывод.

Синтаксис

await scheduler.wait(delay);
await scheduler.wait(delay, options);

Параметры

Возвращаемое значение

A Promise<void> который разрешается через delay миллисекунд. Если AbortSignal передан и прерван до истечения задержки, Promise отклоняется с AbortError.

Примеры

Базовая задержка

Используйте scheduler.wait() чтобы приостановить выполнение на заданное время.

export default {
	async fetch(request) {
		// Wait for 1 second
		await scheduler.wait(1000);
		return new Response("Delayed response");
	},
};
export default {
	async fetch(request): Promise<Response> {
		// Wait for 1 second
		await scheduler.wait(1000);
		return new Response("Delayed response");
	},
} satisfies ExportedHandler;

Повторить с экспоненциальной задержкой

Используйте scheduler.wait() чтобы реализовать задержку между повторными попытками. В этом примере используется экспоненциальная задержка со случайным разбросом.

async function fetchWithRetry(url, maxAttempts = 3) {
	const baseBackoffMs = 100;
	const maxBackoffMs = 10000;

	for (let attempt = 0; attempt < maxAttempts; attempt++) {
		try {
			return await fetch(url);
		} catch (err) {
			if (attempt + 1 >= maxAttempts) {
				throw err;
			}
			const backoffMs = Math.min(
				maxBackoffMs,
				baseBackoffMs * Math.random() * Math.pow(2, attempt),
			);
			await scheduler.wait(backoffMs);
		}
	}
	throw new Error("unreachable");
}

export default {
	async fetch(request) {
		const response = await fetchWithRetry("https://example.com/api");
		return new Response(response.body, response);
	},
};
async function fetchWithRetry(url: string, maxAttempts = 3): Promise<Response> {
	const baseBackoffMs = 100;
	const maxBackoffMs = 10000;

	for (let attempt = 0; attempt < maxAttempts; attempt++) {
		try {
			return await fetch(url);
		} catch (err) {
			if (attempt + 1 >= maxAttempts) {
				throw err;
			}
			const backoffMs = Math.min(
				maxBackoffMs,
				baseBackoffMs * Math.random() * Math.pow(2, attempt),
			);
			await scheduler.wait(backoffMs);
		}
	}
	throw new Error("unreachable");
}

export default {
	async fetch(request): Promise<Response> {
		const response = await fetchWithRetry("https://example.com/api");
		return new Response(response.body, response);
	},
} satisfies ExportedHandler;

Отмена с помощью AbortSignal

Используйте AbortController чтобы отменить ожидающий wait.

export default {
	async fetch(request) {
		const controller = new AbortController();

		// Cancel the wait after 500ms
		setTimeout(() => controller.abort(), 500);

		try {
			await scheduler.wait(5000, { signal: controller.signal });
			return new Response("Wait completed");
		} catch (err) {
			if (err instanceof DOMException && err.name === "AbortError") {
				return new Response("Wait was cancelled", { status: 408 });
			}
			throw err;
		}
	},
};
export default {
	async fetch(request): Promise<Response> {
		const controller = new AbortController();

		// Cancel the wait after 500ms
		setTimeout(() => controller.abort(), 500);

		try {
			await scheduler.wait(5000, { signal: controller.signal });
			return new Response("Wait completed");
		} catch (err) {
			if (err instanceof DOMException && err.name === "AbortError") {
				return new Response("Wait was cancelled", { status: 408 });
			}
			throw err;
		}
	},
} satisfies ExportedHandler;