[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) <xmo@odoo.com>
This commit is contained in:
Xavier Morel
2023-09-01 15:09:49 +00:00
parent 7ef468402d
commit dd4b3c3a66
@@ -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;
}
}
/**