为什么我不能在JavaScript中编写这样的异步代码?

时间:2019-05-23 18:13:27

标签: javascript asynchronous

我想重复执行一些JavaScript,直到收到服务器的响应为止。在此问题的简化版本中,我要“退出!”返回响应时以及myFunction停止执行后将打印到控制台,但是由于某些原因,while循环永远不会终止,并且“ out”变量也永远不会设置为true。我在这里做什么错了?

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!');
    });

1 个答案:

答案 0 :(得分:2)

JavaScript是一种单线程语言。这意味着一次只能执行一个语句。当您遇到while (!out);之类的内容时,此必不可少的会阻止所有执行,并且永远不会继续执行下一条语句。

回调和Promises是此问题的解决方案,它允许不按顺序执行代码的不同部分,但是底层引擎仍然是单线程的。所以当你说

  

我还想确保myFunction已完成执行。

您需要了解,如果myFunction当前正在执行,则代码的任何其他部分都无法执行。从另一角度考虑问题:相反,您要确保在收到响应后不执行myFunction

这是替代解决方案:

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!');
  });

工作原理:myFunction每隔约100毫秒执行一次,直到在then中返回响应为止,此时间隔将被取消(在接下来的100个间隔中不会执行毫秒间隔),并记录Out!