From d7789a48e6e1d105eaf8595e7b254a7c77bf95ab Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Tue, 3 Mar 2020 09:39:19 -0700 Subject: [PATCH] simplify wait implementation --- src/__tests__/wait.js | 11 +++++++++++ src/wait-for-element.js | 3 +++ src/wait.js | 23 ++++------------------- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/__tests__/wait.js b/src/__tests__/wait.js index bbe65e0a6..70e7a83a5 100644 --- a/src/__tests__/wait.js +++ b/src/__tests__/wait.js @@ -17,3 +17,14 @@ test('wait defaults to a noop callback', async () => { await wait() expect(handler).toHaveBeenCalledTimes(1) }) + +test('can timeout after the given timeout time', async () => { + const error = new Error('throws every time') + const result = await wait( + () => { + throw error + }, + {timeout: 8, interval: 5}, + ).catch(e => e) + expect(result).toBe(error) +}) diff --git a/src/wait-for-element.js b/src/wait-for-element.js index cde9db2c0..37804d866 100644 --- a/src/wait-for-element.js +++ b/src/wait-for-element.js @@ -1,5 +1,8 @@ import {wait} from './wait' +// deprecated... TODO: remove this method. People should use a find* query or +// wait instead the reasoning is that this doesn't really do anything useful +// that you can't get from using find* or wait. async function waitForElement(callback, options) { if (!callback) { throw new Error('waitForElement requires a callback as the first parameter') diff --git a/src/wait.js b/src/wait.js index 801d7e9f9..86c7596d5 100644 --- a/src/wait.js +++ b/src/wait.js @@ -23,20 +23,20 @@ function wait( } = {}, ) { if (interval < 1) interval = 1 - const maxTries = Math.ceil(timeout / interval) - let tries = 0 return new Promise((resolve, reject) => { - let lastError, lastTimer + let lastError const overallTimeoutTimer = setTimeout(onTimeout, timeout) + const intervalId = setInterval(checkCallback, interval) const observer = newMutationObserver(checkCallback) runWithRealTimers(() => observer.observe(container, mutationObserverOptions), ) + checkCallback() function onDone(error, result) { clearTimeout(overallTimeoutTimer) - clearTimeout(lastTimer) + clearInterval(intervalId) setImmediate(() => observer.disconnect()) if (error) { reject(error) @@ -58,21 +58,6 @@ function wait( function onTimeout() { onDone(lastError || new Error('Timed out in wait.'), null) } - - function startTimer() { - lastTimer = setTimeout(() => { - tries++ - checkCallback() - if (tries > maxTries) { - onTimeout() - return - } - startTimer() - }, interval) - } - - checkCallback() - startTimer() }) }