From dd4b3c3a66d2b4708fb29c1cc9dbd5c67e173db5 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 1 Sep 2023 15:09:49 +0000 Subject: [PATCH] [IMP] web: simplify waitForCondition `waitForCondition` is written in a rather old style with a recursive `setTimeout` to handle the delay / debounce between checks. The code is rather hard to follow, and unnecessarily so: the code can be rewritten as an iterative async function which is a lot simpler. Important change: `waitForCondition` now immediately checks for the condition instead of waiting `interval` milliseconds before doing so. This is because the conventional usage is for it to be preceded by an `await triggerClick`, which includes an `await waitForNextAnimationFrame()`. As a result there are good odds the click has already been processed by the time `waitForCondition` runs. closes odoo/odoo#133645 Signed-off-by: Xavier Morel (xmo) --- .../static/src/webclient/clickbot/clickbot.js | 34 ++++++------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/addons/web/static/src/webclient/clickbot/clickbot.js b/addons/web/static/src/webclient/clickbot/clickbot.js index 5c32ade176c..53e1ac940ce 100644 --- a/addons/web/static/src/webclient/clickbot/clickbot.js +++ b/addons/web/static/src/webclient/clickbot/clickbot.js @@ -117,33 +117,19 @@ * Wait a certain amount of time for a condition to occur * * @param {function} stopCondition a function that returns a boolean + * @param {Number} tl the maximum wait time before stopping, in milliseconds * @returns {Promise} that is rejected if the timeout is exceeded */ - function waitForCondition(stopCondition, tl = 30000) { - return new Promise(function (resolve, reject) { - const interval = 25; - let timeLimit = tl; - - function checkCondition() { - if (stopCondition()) { - resolve(); - } else { - timeLimit -= interval; - if (timeLimit > 0) { - // recursive call until the resolve or the timeout - setTimeout(checkCondition, interval); - } else { - console.error( - "Timeout, the clicked element took more than", - tl / 1000, - "seconds to load" - ); - reject(); - } - } + async function waitForCondition(stopCondition, tl = 30000) { + const interval = 25; + let timeLimit = tl; + while (!stopCondition()) { + if (timeLimit <= 0) { + throw new Error(`Timeout, the clicked element took more than ${tl / 1000} seconds to load`) } - setTimeout(checkCondition, interval); - }); + await new Promise(resolve => setTimeout(resolve, interval)); + timeLimit -= interval; + } } /**