简体   繁体   中英

Why can't I write asynchronous code like this in JavaScript?

I want to execute some JavaScript repeatedly until I get a response from the server. In this simplified version of the problem, I want "Out!" to be printed to the console when the response is returned and after myFunction has stopped executing, but for some reason, the while loop is never terminated, and the "out" variable never gets set to true. What am I doing wrong here?

let keepGoing = true;   
let out = false;


function myFunction() {
    if (keepGoing) {
        console.log('Still going!');
        setTimeout(myFunction, 100);
    }
    else {
        out = true;
    }
}

setTimeout(myFunction, 100);

fetch('https://jsonplaceholder.typicode.com/todos/1')
    .then((response) => {
       keepGoing = false;
       while (!out);
       console.log('Out!');
    });

JavaScript is a single-threaded language. This means that only one statement can ever be executed at a time. When you have something like while (!out); , this by necessity will block all execution and will never continue to the next statement.

Callbacks and Promises are solutions to this problem that allow different portions of code to be executed out of sequence, but still, the underlying engine is single-threaded. So when you say,

I also want to ensure that myFunction has finished executing.

You need to understand that there is no way for any other portion of code to execute if myFunction is currently executing. Think about this the other way around: what you want instead is to ensure that myFunction doesn't execute after the response is received.

Here's an alternative solution:

 function myFunction() { console.log('Still going!'); } const intervalId = setInterval(myFunction, 100); fetch('https://jsonplaceholder.typicode.com/todos/1') .then((response) => { clearInterval(intervalId); console.log('Out!'); }); 

How it works: myFunction will be executed every ~100 ms until the response is returned in then , at which point the interval will be canceled (it won't be executed on the next 100 ms interval), and Out! is logged.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM