Skip to content

Instantly share code, notes, and snippets.

@dmitriid

dmitriid/defer.ts

Created Jul 27, 2017
Embed
What would you like to do?
let deferreds = {} as { [key : string] : any[] }
let deferred_timers = {} as { [key : string] : number }
/*
* If you're waiting wor a `window.something`, and are not sure when it
* will appear (for example, you defer async load it), you can do the following:
*
* defer('something', (something) => ...)
*
* You can also check nested props:
*
* defer('google.maps', (GoogleMaps) => ...)
*
*
* defer will poll window['something'], and when it appears, it will
* invoke the function with window['something']
*
* Note: it will poll the window object for 90 seconds, and then will stop
*
*/
export default function defer(what : string, action : Function) : void {
const executeAndLog = (whatObj, actionFunc) => {
if(what === 'mixpanel') {
// console.log(what, actionFunc.toString())
}
actionFunc(whatObj)
}
const obj = checkNested(window, what.split('.'))
if(obj !== void 0) {
const actions = deferreds[what] || []
actions.forEach((action) => executeAndLog(obj, action))
executeAndLog(obj, action)
} else {
if(deferreds[what] === void 0) {
deferreds[what] = []
}
deferreds[what].push(action)
if(deferred_timers[what] === void 0) {
let counter = 0
deferred_timers[what] = setInterval(() => {
const obj = checkNested(window, what.split('.'))
if(obj !== void 0) {
clearInterval(deferred_timers[what])
const actions = deferreds[what] || []
actions.forEach((action) => executeAndLog(obj, action))
} else {
counter = counter + 1
if(counter > 300) {
clearInterval(deferred_timers[what])
}
}
}, 300)
}
}
}
function checkNested(obj, what) {
for(let i = 0; i < what.length; i++) {
if(!obj || !obj.hasOwnProperty(what[i])) {
return void 0
}
obj = obj[what[i]]
}
return obj
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment