Skip to content
Snippets Groups Projects
Verified Commit 37aeb339 authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

fix: handle updates better

parent c5ecc0fe
Branches
Tags
No related merge requests found
......@@ -60,6 +60,18 @@ export { Updater, addObjectWithUpdaterToElement };
*/
const timerElementEventHandlerSymbol = Symbol("timerElementEventHandler");
/**
* @private
* @type {symbol}
*/
const pendingDiffsSymbol = Symbol("pendingDiffs");
/**
* @private
* @type {symbol}
*/
const processingSymbol = Symbol("processing");
/**
* The updater class connects an object with the DOM. In this way, structures and contents in the DOM can be
* programmatically adapted via attributes.
......@@ -85,6 +97,7 @@ const timerElementEventHandlerSymbol = Symbol("timerElementEventHandler");
* @summary The updater class connects an object with the dom
*/
class Updater extends Base {
/**
* @since 1.8.0
* @param {HTMLElement} element
......@@ -117,37 +130,48 @@ class Updater extends Base {
getCheckStateCallback.call(this),
);
this[pendingDiffsSymbol] = [];
this[processingSymbol] = false;
this[internalSymbol].subject.attachObserver(
new Observer(() => {
const s = this[internalSymbol].subject.getRealSubject();
const diffResult = diff(this[internalSymbol].last, s);
this[internalSymbol].last = clone(s);
const real = this[internalSymbol].subject.getRealSubject();
const diffResult = diff(this[internalSymbol].last, real);
this[internalSymbol].last = clone(real);
this[pendingDiffsSymbol].push(diffResult);
return this.#processQueue();
}),
);
}
const promises = [];
/**
* @private
* @return {Promise}
*/
async #processQueue() {
if ( this[processingSymbol]) {
return Promise.resolve();
}
this[processingSymbol] = true;
while (this[pendingDiffsSymbol].length > 0) {
const diffResult = this[pendingDiffsSymbol].shift();
for (const [, change] of Object.entries(diffResult)) {
promises.push(
new Promise((resolve, reject) => {
getWindow().requestAnimationFrame(() => {
await new Promise((resolve, reject) => {
try {
removeElement.call(this, change);
insertElement.call(this, change);
updateContent.call(this, change);
updateAttributes.call(this, change);
resolve();
} catch (error) {
reject(error);
} catch (err) {
reject(err);
}
});
}),
);
}
}
return Promise.all(promises);
}),
);
this[processingSymbol] = false;
}
/**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment