Skip to content

WilliCommer/BeginUpdate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 

Repository files navigation

BeginUpdate Method for JavaScript

Increase performance of batch updates

What is it good for ?

For example, you have a function setValue(name, vale) that will change a value and render the user interface.

setValue (name, value) {
	this.values[name] = value;
	this.checkValue();
	this.render();
},

That function will be called multiple times in your program and every call will render the UI again.

submit (values) {
	Object.keys.forEach( k => this.setValue( k, values[k]) );
}

In JavaScript this problem will usually solved with debounce function. If you don't know debounce, read this. It is optimal in order to solve the problem of unnecessary changes at a later stage. But you can tackle the problem at the root, with a simple pattern, that came up in the 1990's with Delphi and Windows.

Before starting a batch update, give a notification with beginUpdate() and at the end call endUpdate(). The implementation is very simple, beginUpdate will increment a counter and endUpdate decrement this counter and if it's zero the update function will be called. That's it.

Simple Updater

function Updater ( update ) {
	var counter = 0;
    return {
        begin () { 
            counter += 1; 
        },
        end () { 
            counter -= 1; 
            if (counter = 0) update();
        }
    }
}    

It is recommended to use the function in a try - finally block, to make sure the counter is zero at the end.

const update = new Updater( () => {
	console.log('update');
});
   
update.begin();
try {
	for (let i=0; i < 100; i++) {
    	addItem(i);
  	}
}
finally {
	update.end();
}

Final Updater

My final version provides a function do() that calls a function in a try block and takes care about binding.

function Updater ( update, that ) {
	var counter = 0;
	if (that) update = update.bind(that);

    return {
        
        begin () { 
            return counter += 1; 
        },

        end () { 
            counter -= 1; 
            if (counter <= 0) {
                update();
                return true;
            }
            return false;
        },

        do (func) {
            counter += 1; // begin
            try {
                if (func) {
                    if (that) func = func.bind(that);
                    func();
                }
            }
            finally {
                counter -= 1; // end
                if (counter <= 0) update();
            }
            return counter === 0;
        }
    }
}    

Usage

Example:

const testObj = {

	updater: new Updater(this.update, testObj),

	addItem_simple (i) {
		updater.begin();
		try {
			addX(i);
		}
		finally {
			updater.end();
		}
	},

	addItems_do (items) {
		updater.do( () => items.forEach(i => addX(i)) );
	},
	
	addItem_easy (i) {
		addX(i);
		updater.do();
	}
	
	update () {
		renderMe(testObj);
	}
}

References

About

BeginUpdate Method for JavaScript

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published