This function will certainly do the job. Couple of nitpicks:
You might consider replacing
el !== null && el.length !== 0withel && "nodeType" in elEvery time the elementFinder is called, you are defining a new function in memory called
checkerFn, instead you can reuse it, but probably you'll have to passintervalandmaxTriesas a parameter to it:
const finder = function(){
function elementFinder (..){
...
}
function checkerFn (..) {
...
}
return elementFinder;
}();
Consider switching to
requestAnimationFrame(rAF); for tasks/animations that does not have to be executed with sub-millisecond precision can be handled byrAF. The good thing with rAF is that if the tab is out of focus, it won't run.If you are simultaneously searching for several elements at the same time, multiple
setTimeout/rAFcalls will have to be executed. For a couple of elements/tasks this is not an overhead, but if you have many, it makes sense to execute 1setTimeout/rAFper 'tick' and process the tasks in there. For this you will need to modify your code to store tasks in some sort of ledger.I see that you are using Promises, which is a great idea, perhaps to return a
thenablefrom your function which you can execute other tasks once the element is available. The problem with Promises is that you cannot 'break' out of it, you'll have to add some sort of breaking mechanism to your code. Also if you want to seamlessly support evergreen and older browsers, you'll need a Promise polyfill.Although Promises bring a lot of convenience, they certainly bring an overhead (see perf differences between Native Promises and Bluebird's version). If the sole purpose is to return a
thenablefor constructing chains, this can certainly be implemented using onlysetTimeout/rAF. This alleviates the need for polyfill for olderbrowsers.