Help understanding Promises

Hi guys,

I’ve just made a start on the Graceful asynchronous programming article and wanted to clarify something.

In the first example given, a video chat app is discussed and an async code block is detailed which uses the method ‘getUserMedia()’. This method, as I understand, asks for video and audio and once both values are ‘true’ continues with the code. I’m assuming that if one or both are ‘false’ then the promise will fail and the catch() method will run.

I’m wondering since initially, the video and audio properties will have a value of ‘false’, why doesn’t the promise return as fail and the code jump straight to catch()? How long does the browser wait for the values of video and audio to change to ‘true’ and how does it know to do this? I skimmed through the reference page for the getUserMedia() method but couldn’t find an answer.

The code from the example I’m referencing is below. More specifically, I’m asking about line 3.

I’m not very familiar with Promises and the terminology so if what I’m asking isn’t clear, please let me know and I’ll try to rephrase the question.

Also, I read this paragraph a few times but it doesn’t make any sense to me.

The important thing here is that the getUserMedia() call returns almost immediately, even if the camera stream hasn’t been obtained yet. Even if the handleCallButton() function has already returned to the code that called it, when getUserMedia() has finished working, it calls the handler you provide. As long as the app doesn’t assume that streaming has begun, it can just keep on running.

Any help would be appreciated.

Thanks!

Regards,

Jared

The following things take place, in that order:

  1. function handleCallButton gets called somehow;
  2. handleCallButton calls setStatusMessage immediately;
  3. setStatusMessage does its work, then returns;
  4. handleCallButton calls navigator.mediaDevices.getUserMedia(...);
  5. getUserMedia immediately responds “ok, I’m on it” (that’s the Promise);
  6. function handleCallButton calls then and catch, which chains additional stuff after the Promise, but they’re not executed yet;
  7. function handleCallButton is now finished;
  8. the browser continues its work, displaying html, css, running additional js, etc.;
  9. at some point, getUserMedia actually starts working – in truth, this method may have started before now, but everything behaves as if it only started working now;
  10. getUserMedia will need additional information from your operating system, from the user, etc. – it gets all this information in its own time, without stopping the page or the browser from executing;
  11. once getUserMedia has finished gathering the information, it either resolves its Promise (to respond “yes”) or reject the Promise (to respond “no”);
  12. once either happens and once the browser is ready to execute JavaScript code, if the Promise was resolved, the code inside then is executed or if the Promise was rejected, the code inside catch is executed.

Now, let’s return to your questions one by one:

This method, as I understand, asks for video and audio and once both values are ‘true’ continues with the code

Not really. As exposed above, it continues the code (by resolving or rejecting the Promise) once it has gathered all the information it needs (and once the browser is ready to execute that code).

I’m assuming that if one or both are ‘false’ then the promise will fail and the catch() method will run.

Not really. For one thing, the catch() method always runs. It just doesn’t do much – it just tells the Promise “by the way, if you’re rejected, that’s what you need to do.” Also, if its information gathering concludes that it cannot provide the video or the audio (typically because the user rejected, but hey, maybe because the user is using a screenreader instead of your typical browser configuration), the promise will be rejected and the method registered thanks to catch() will run.

I’m wondering since initially, the video and audio properties will have a value of ‘false’, why doesn’t the promise return as fail and the code jump straight to catch()?

Well, in the snippet you paste, the developer sets the values of properties video and auto to true. These values don’t change. What changes is the information gathered by getUserMedia, which goes internally from something along the lines of “I don’t know yet” to “yes, here’s a chatStream” or “no, here’s an error”.

Does this answer your questions?