for clarity: moved here from stackoverflow after being pointed to Code Review being the better place for this question
I love async/await and Promises since I got my hands on them. And I might be overdoing it, but it feels like there should be a good and readable way to utilize async/await to get a little closer to a flow like, functionalISH programming style.
I would love to not have to only use async/await to wait for web resources to come back but also to wait for user input when I await it.
So far i have some code working similar to this shortened demo where I wrap a one time only EventListener into a Promise:
//// MAIN ///////
(async function(){
//...do some async await stuff here... fetching stuff from a server
// let services = await fetch(...) for example
let services = [{url:"x",label:"1"},{url:"y",label:"2"},{url:"z",label:"3"}]
let service_chosen = await showServicesToUserAndAwaitInput(services);
console.log("service_chosen:",service_chosen);
// ... go on....
})()
//// END MAIN /////
async function showServicesToUserAndAwaitInput(services){
if (services.length < 1){return null}
let choice = null;
let serviceList = document.querySelector("#serviceList");
// show list element
serviceList.classList.remove("hidden")
// create some elements for the user to interact with
for (let service of services){
let button = document.createElement("BUTTON");
button.innerHTML = service.label;
button.addEventListener("click",function(){
document.dispatchEvent(
new CustomEvent('serviceChosen', { detail:service })
)
});
serviceList.appendChild(button);
}
// returns promise with one time only event listener
return new Promise((resolve,reject)=>{
document.addEventListener("serviceChosen",function(e){
serviceList.classList.add("hidden") // hide again for we are done
resolve(e.detail)
},{ once: true })
})
}
.hidden{
visibility: hidden
}
<div id="serviceList" class="hidden">
</div>
But something about this use of the EventListener bugs me. Also: I use a promise that always resolves, which also seems strange.
On the upside: I get to read the code top to bottom and can follow the user flow within the MAIN without having to chase down events, callbacks and so on.
Yet, it feels like I am reinventing something somebody else might have already normed. So:
Is there a better way to achieve this? Are there best practices to work with user interactions or other DOM events in a async and/or thenable way?