UNPKG

marko

Version:

UI Components + streaming, async, high performance, HTML templating for Node.js and the browser.

95 lines (80 loc) 2.76 kB
"use strict"; var updatesScheduled = false; var batchStack = []; // A stack of batched updates var unbatchedQueue = []; // Used for scheduled batched updates var setImmediate = require("@internal/set-immediate").___setImmediate; /** * This function is called when we schedule the update of "unbatched" * updates to components. */ function updateUnbatchedComponents() { if (unbatchedQueue.length) { try { updateComponents(unbatchedQueue); } finally { // Reset the flag now that this scheduled batch update // is complete so that we can later schedule another // batched update if needed updatesScheduled = false; } } } function scheduleUpdates() { if (updatesScheduled) { // We have already scheduled a batched update for the // nextTick so nothing to do return; } updatesScheduled = true; setImmediate(updateUnbatchedComponents); } function updateComponents(queue) { // Loop over the components in the queue and update them. // NOTE: It is okay if the queue grows during the iteration // since we will still get to them at the end for (var i = 0; i < queue.length; i++) { var component = queue[i]; component.___update(); // Do the actual component update } // Clear out the queue by setting the length to zero queue.length = 0; } function batchUpdate(func) { // If the batched update stack is empty then this // is the outer batched update. After the outer // batched update completes we invoke the "afterUpdate" // event listeners. var batch = []; batchStack.push(batch); try { func(); } finally { try { // Update all of the components that where queued up // in this batch (if any) updateComponents(batch); } finally { // Now that we have completed the update of all the components // in this batch we need to remove it off the top of the stack batchStack.length--; } } } function queueComponentUpdate(component) { var batchStackLen = batchStack.length; if (batchStackLen) { // When a batch update is started we push a new batch on to a stack. // If the stack has a non-zero length then we know that a batch has // been started so we can just queue the component on the top batch. When // the batch is ended this component will be updated. batchStack[batchStackLen - 1].push(component); } else { // We are not within a batched update. We need to schedule a batch update // for the nextTick (if that hasn't been done already) and we will // add the component to the unbatched queue scheduleUpdates(); unbatchedQueue.push(component); } } exports.___queueComponentUpdate = queueComponentUpdate; exports.___batchUpdate = batchUpdate;