Skip to content

Instantly share code, notes, and snippets.

@ccnokes
Last active September 22, 2020 02:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ccnokes/a6775e42b1f87cceb284e2250aee1795 to your computer and use it in GitHub Desktop.
Save ccnokes/a6775e42b1f87cceb284e2250aee1795 to your computer and use it in GitHub Desktop.
Online/offline emitter in vanilla JS
function createOnlineEmitter() {
let cbs = []; //array of registered callbacks for the event
let unsub; //function for removing the main event listener
//this is the main event listener that gets registered with window.online/offline event
const mainListener = (isOnline) => {
//call all the subscribed callbacks
cbs.forEach(cb => cb(isOnline));
};
const registerMainListener = () => {
const boundOnline = mainListener.bind(null, true);
const boundOffline = mainListener.bind(null, false);
window.addEventListener('online', boundOnline);
window.addEventListener('offline', boundOffline);
//return unsubcribe functionality in a closure
return function unsubscribe() {
window.removeEventListener('online', boundOnline);
window.removeEventListener('offline', boundOffline);
};
};
const addCb = (cb) => {
cbs.push(cb);
//register main listener only once
//use existence of `unsub` as indicator if main event listener is added or not
if(!unsub) {
unsub = registerMainListener();
}
};
const removeCb = (cb) => {
const index = cbs.indexOf(cb);
if(index > -1) {
cbs.splice(index, 1);
}
//if no callbacks left, remove main event listener
if(cbs.length === 0 && unsub) {
unsub();
unsub = null;
}
};
return function initOnlineEmitter(cb) {
addCb(cb);
//call it async with the initial val
setTimeout(() => {
cb(navigator.onLine);
});
//return unsubscribe function to caller
return removeCb.bind(null, cb);
};
}
// implement it
const onlineEmitter = createOnlineEmitter();
let unsub = onlineEmitter(isOnline => console.log(isOnline));
unsub();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment