Você já se perguntou se é possível pausar a execução de uma função até que um evento seja disparado? Bem, no ES6 é!
function listen(){
var gen = suspend();
var wait = function(){
var done = 0;
return (e)=>done||(done=1,gen.next());
}
gen.next();
function* suspend(){
//synchronous events?
console.log('waiting for doc. load');
yield window.addEventListener('load',wait());
console.log('loaded, waiting for click');
var click = yield document.addEventListener('click',wait());
console.log('clicked');
}
}