I'm building a basic hangman game. I have created one class called Hangman and it only has two methods:fetchWord and displayChoices. The fetchWord method takes an url parameter and fetches the word from that specific source. The displayChoices method does what the name says. First, create a list of radio buttons which contains the corresponding letters and display them on the webpage. The only problem with my code is the fetchWord method. Here is the code -- I will explain the issue later.
<body>
<script>
class Hangman {
fetchWord(url) {
fetch(url).then(data=>data.json().then(word=>this.word=word[0]));//fetches the word from a random source.
}
//Create the required elements and put them on the page.
displayChoices() {
const choices = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
choices.forEach(function(choice) {
const label = document.createElement('label');
label.innerText=choice;
label.id=choice;
const element = document.createElement('input');
element.type='radio';
element.value=choice;
element.id=choice;
label.appendChild(element);
document.body.appendChild(label);
});
}
}
const a = new Hangman();
a.fetchWord(' https://random-word-api.herokuapp.com/word ');
a.displayChoices();
document.write(a.word);
</script>
</body>
When you run the code, the radio buttons populate. This is exactly what I want. However, on the bottom of the page, it shows undefined. I think this is an async/await problem, because when I added setTimeout and wrapped the document.write(a.word) in it, it works totally fine. I have written my thought process below in case you want to see it.
First, the class is created .Next, I run the fetchWord method which adds it to the stack.It encounters the fetch API, so it puts it into the browser's call stack space.Now, the fetch API returns the promise, and it was popped out of the stack.The then function is added to the stack -- it runs in the browser's API call stack.When it's done, it puts the callback into the microtask queue.Next, the fetchWord function finally returns and the call stack is empty.Since the call stack is empty, the event loop checks if there are any microtasks that it needs to do. As mentioned earlier, it does. So it runs the callback which was put onto the stack by the then method of Promise.Since this function runs another then, this callback is pushed into the microtask queue.When the callback exits, it is popped out of the stack. Since microtask queues have a higher role than any of the macrotask queues, the event loop keeps running any pending microtasks. As a result, the callback put onto the microtask queue is pushed onto the stack and executed. Once it is done executing, it is popped out of the stack. Next, it runs the displayChoices method. After the displayChoices returns, the document.write is run. Since the callback pushed onto the microtask queue is executed before the document.write, the result (a.word) should be available. However, it is not. How should I construct my code so that it produces the expected result?
The problems have been described in the post.