(
callback: () => Promise<T> | T,
options: WaitForOptions = {},
)
| 262 | const realSetTimeout = setTimeout; |
| 263 | |
| 264 | export async function waitFor<T>( |
| 265 | callback: () => Promise<T> | T, |
| 266 | options: WaitForOptions = {}, |
| 267 | ): Promise<T> { |
| 268 | const waitTime = options.timeout ?? 100; |
| 269 | const interval = options.interval ?? 0; |
| 270 | const stack = new Error().stack; |
| 271 | |
| 272 | const deadline = realNow() + waitTime; |
| 273 | let i = 0; |
| 274 | let lastError: any | undefined; |
| 275 | |
| 276 | while (true) { |
| 277 | try { |
| 278 | return await callback(); |
| 279 | } catch (cause) { |
| 280 | lastError = cause; |
| 281 | } |
| 282 | |
| 283 | i++; |
| 284 | |
| 285 | if (deadline < realNow()) { |
| 286 | throw Object.assign( |
| 287 | new Error( |
| 288 | `Timed out after ${waitTime}ms and ${i} attempts. ` + |
| 289 | `Last error: ${lastError?.message ?? 'condition returned false'}`, |
| 290 | ), |
| 291 | { |
| 292 | stack: stack + `Last error: ${lastError?.stack ?? 'condition returned false'}`, |
| 293 | }, |
| 294 | ); |
| 295 | } |
| 296 | |
| 297 | // Guarantee a macro-task between retries. |
| 298 | await new Promise((resolve) => void realSetTimeout(resolve, interval)); |
| 299 | } |
| 300 | } |
no test coverage detected
searching dependent graphs…