用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/bobmatnyc/claude-mpm --skill condition-based-waiting命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| name | Condition-Based Waiting |
| description | Replace arbitrary timeouts with condition polling for reliable async tests |
| when_to_use | when tests have race conditions, timing dependencies, or inconsistent pass/fail behavior |
| version | 1.1.0 |
| languages | all |
| progressive_disclosure | {"entry_point":{"summary":"Replace arbitrary timeouts with condition polling for reliable async tests","when_to_use":"Tests with setTimeout/sleep, flaky tests, or timing-dependent async operations","quick_start":"1. Identify arbitrary delays in tests (setTimeout, sleep, time.sleep())\n2. Replace with condition-based waiting (waitFor pattern)\n3. Use domain-specific helpers for common scenarios\nSee @example.ts for complete working implementation\n","core_pattern":"// ❌ Guessing at timing\nawait new Promise(r => setTimeout(r, 50));\n\n// ✅ Waiting for condition\nawait waitFor(() => getResult() !== undefined);\n"},"references":[{"path":"references/patterns-and-implementation.md","purpose":"Detailed waiting patterns, implementation guide, and common mistakes","when_to_read":"When implementing waitFor or debugging timing issues"}]} |
| effort | medium |
Flaky tests often guess at timing with arbitrary delays. This creates race conditions where tests pass on fast machines but fail under load or in CI.
Core principle: Wait for the actual condition you care about, not a guess about how long it takes.
digraph when_to_use {
"Test uses setTimeout/sleep?" [shape=diamond];
"Testing timing behavior?" [shape=diamond];
"Document WHY timeout needed" [shape=box];
"Use condition-based waiting" [shape=box];
"Test uses setTimeout/sleep?" -> "Testing timing behavior?" [label="yes"];
"Testing timing behavior?" -> "Document WHY timeout needed" [label="yes"];
"Testing timing behavior?" -> "Use condition-based waiting" [label="no"];
}
Use when:
setTimeout, sleep, time.sleep())Don't use when:
// ❌ BEFORE: Guessing at timing
await new Promise(r => setTimeout(r, 50));
const result = getResult();
expect(result).toBeDefined();
// ✅ AFTER: Waiting for condition
await waitFor(() => getResult() !== undefined);
const result = getResult();
expect(result).toBeDefined();
| Scenario | Pattern |
|---|
| Wait for event | waitFor(() => events.find(e => e.type === 'DONE')) |
| Wait for state | waitFor(() => machine.state === 'ready') |
| Wait for count | waitFor(() => items.length >= 5) |
| Wait for file | waitFor(() => fs.existsSync(path)) |
| Complex condition | waitFor(() => obj.ready && obj.value > 10) |
Generic polling function:
async function waitFor<T>(
condition: () => T | undefined | null | false,
description: string,
timeoutMs = 5000
): Promise<T> {
const startTime = Date.now();
while (true) {
const result = condition();
if (result) return result;
if (Date.now() - startTime > timeoutMs) {
throw new Error(`Timeout waiting for ${description} after ${timeoutMs}ms`);
}
await new Promise(r => setTimeout(r, 10)); // Poll every 10ms
}
}
See @example.ts for complete implementation with domain-specific helpers (waitForEvent, waitForEventCount, waitForEventMatch).
For detailed patterns, implementation guide, and common mistakes, see @references/patterns-and-implementation.md
From debugging session (2025-10-03):