I’m building a React Guitar, and on page load, I’m creating the wav files for the sounds, which takes a couple of seconds. I’m unsure how to implement something like a “loading” bar.
I’ve struggled with this problem in several projects but never quite got my head around it. Do I need await/async or promises for that?
After making it work with a callback, I’m now trying to do the same with async/await instead. For easier reference, here’s the setup:
createAudioFiles.js
export function createAudioFiles(){
// big block of code
return fileCache
}
playGuitar.js
import {createAudioFiles} from '../utils/createAudioFiles.js';
/* this is what I tried: */
const getAudio = async function(){
let result = await createAudioFiles();
console.log(result) // result is an empty fileCache
return result;
}
const audioFiles = getAudio();
console.log(audioFiles); // Promise(pending)
I’m obviously missing something. I’ve read that even if my async function doesn’t explicitly return a Promise, it will automatically be wrapped in a Promise that will resolve to the value it’s returning.
Why is result an empty fileCache? Shouldn’t the await keyword make sure that result is assigned AFTER the complete fileCache has been created and returned from my createAudioFiles function?
export async function createAudioFiles(){
// big block of code
return await fileCache
}
It doesn’t help. In fact I don’t even see a difference in my console.logs (I’ve added another one where I log audioFiles with a timeout after 2 seconds). At that point, it’s a Promise with status fulfilled. But when I inspect it with the dev tools, it still holds an empty fileCache. I think I need to “unwrap” that Promise somehow to get my fileCache. I just don’t know how.
I actually find that particular article terribly confusing. It’s not the first time I’m digging my way through it but I just. don’t. get. it.
They write that using async/await allows it to write async code without the explicit use of Promises. But later in all their examples, they’re doing exactly that.
They also write that the difference between return fileCache and return await fileCache is that return await will WAIT for fileCache to resolve. Why isn’t that happening in my code?
Why are you returning a promise from createAudioFiles() now? I thought that wasn’t necessary with async/await?
Thanks for the edit, nonetheless. I guess I’ll have to learn it the hard way, which means going through the docs and code along with every single example until it finally enters my brain.
Not really, here’s the part from the docs:
This highlights the subtle difference between return foo; and return await foo; — return foo immediately returns foo and never throws, even if foo is a Promise that rejects. return await foo will wait for foo to resolve or reject if it’s a Promise, and throws before returning if it rejects.
Probably only relevant when you have to handle errors but still good to know.
OH alright this explains why it takes two seconds longer for the files to be created/the function to return.
I’m still going through your edits and I’m still super confused, for example as to why you’ve moved the execution of createAudioFiles() into my createGuitarNotes() function, those two are totally unrelated, and I’m still puzzled why my fileCache always seems to be just an empty fileCache when I log it, no matter where or when I log it…
That’s why I had created a small getAudio() function in my original approach, so at least I got that half-right… I’ve merged your solution into that, because
isn’t quite right, createGuitarNotesArr() only creates an array for the fretboardValsToNote() function (sort of a look-up table), while my audioFiles are used by the playNote function which in turn is used by all functions I’m exporting, … but I’m just nitpicking here.
Point is it works now with my modified getAudio() function.
const getAudio = async function(){
let result = await createAudioFiles();
return result
}
const audioFiles = getAudio();
I’m not 100% sure I’ve understood why yet, but it’s good to know what I’ve done wrong (here, and whenever I tried something with async/await before).
Also found out why my fileCache seemed to be empty. I’m just stupid, some entries must be empty because a guitar doesn’t have all the notes that a full 88-key piano has, and the fileCache is built with identical structure for both instruments.