跳转到内容
搜索文档

Scheduler

最后更新 查看 MarkdownAgent 设置

背景

scheduler 全局对象提供基于 WICG Scheduling APIs 提案 的任务调度 API。Workers 目前实现了 scheduler.wait() 方法。

scheduler.wait() 返回一个 Promise,在给定的毫秒数后解析。它是 setTimeout() 的可 await 替代方案,无需回调。

与 Workers 中的其他计时器一样,部署到 Cloudflare 后,scheduler.wait() 在 CPU 执行期间不会推进。这是缓解 Spectre 攻击的安全措施。在本地开发中,无论是否发生 I/O,计时器都会推进。

Syntax

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

参数

  • delay number

    • 返回的 Promise 解析之前等待的毫秒数。
  • options object optional

    • 等待操作的可选配置。

    • signal AbortSignal optional

      • 用于取消等待的 AbortSignal。当信号被中止时,返回的 Promise 将以 AbortError 拒绝。

返回值

一个在 delay 毫秒后解析的 Promise<void>。如果提供了 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 取消待处理的等待。

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;

相关资源

这篇文档对您有帮助吗?