← Cloudflare Workers / workers / runtime-apis
Планировщик
Контекст
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);Параметры
-
delayчисло- Количество миллисекунд ожидания перед тем, как возвращаемый Promise будет выполнен.
-
optionsобъект, необязательный-
Необязательная конфигурация для операции ожидания.
-
signalAbortSignal необязательно- Одна
AbortSignalкоторый отменяет ожидание. Когда сигнал прерывается, возвращенный Promise отклоняется сAbortError.
- Одна
-
Возвращаемое значение
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;Дополнительные материалы
- Таймеры,
setTimeout()иsetInterval()API - Производительность и таймеры,
performance.now()и поведение таймеров в части безопасности - AbortController и AbortSignal : отменяет асинхронные операции
- предложение WICG Scheduling APIs ↗ : спецификация, на которой основан этот API