0

I have the following JavaScript code:

async function awaitFetch(urlString) {
    try {
      let status = await fetch(urlString);
      return status;
    } catch(e) {
        alert(e);
    }
}

let response = null; 
let url = 'https://stackoverflow.com';
awaitFetch(url).then(function (resolve) { response = resolve.status });
while (response === null) {};
console.log(response);

The while loop runs eternally, and I find that response never changes from null because the promise never resolves. Why does my code behave this way? I expect the loop to stop executing when the asynchronous code turns response into 200 or what have you (something besides null), but that never happens. The loop executes forever, and my console.log() is never run. Why is this?

All that I'm really trying to do is pause execution until response is an actual response, and then log it. I also have the constraint that I can't put the console.log() within the .then(). If the event loop is blocked by my while loop, what is a way that I can pause execution until response updates without putting my console.log() in an async function or a .then()??

JCollier
  • 1,102
  • 2
  • 19
  • 31
  • Keep in mind that async does not mean multi-threaded. If you want your JS multi-threaded, you can use Web Workers. Async just means the code will run a little bit at a time, with other code in between, until it's done and it settles. A while loop running in between never finishes, so it can't return to check on the async code, and you get an infinite blocking loop. – IceMetalPunk Dec 16 '19 at 20:26

2 Answers2

0

JavaScript is single-threaded, so a while loop will block all processing. Post-completion logic for async tasks still must run on that same single thread.

If you want to wait on a Promise, instead of doing a spin loop, use await:

async function() {
  let url = 'https://stackoverflow.com';
  const { status: response } = await awaitFetch(url);
  console.log(response);
}

...or put your logic in the .then callback.

awaitFetch('https://stackoverflow.com')
  .then(function (resolve) { 
    const response = resolve.status 
    console.log(response);
  });
Jacob
  • 77,566
  • 24
  • 149
  • 228
  • I can't have my console.log() in the .then() or in the async function. In reality, my log function represents thousands of lines of code that need to wait for me to get response. For various reasons, they need to be free standing. – JCollier Dec 16 '19 at 20:43
  • 1
    There's no way to avoid the use of callback functions or `await` for asynchronous code in JavaScript. Maybe you could rephrase the question with more details on why you can't use an async function for this. There's almost certainly a way that you can indeed use an async function. – Jacob Dec 16 '19 at 20:52
-3

Can you try putting your call to awaitFetch inside your while loop block?

itman312
  • 11
  • 1
  • 8