简体   繁体   English

for循环中的setTimeout,变量未更改

[英]setTimeout in a for loop, variable not changing

I'm a bit of a beginner to JavaScript and I've been trying to figure this out for at least two hours. 我是JavaScript的初学者,并且我一直在设法弄清楚至少两个小时。 If someone could explain to me why this is happening, it'll be great! 如果有人可以向我解释为什么会这样,那就太好了!

function slowDouble(x, callback) {
    setTimeout(function() {
    callback(2 * x);
  }, 500);
}

function slowDoubleTenTimes(x, callback) {
    for (i = 0; i < 10; i++) {
        slowDouble(x, function(result) {
            x = result;
        });
    }

    callback(x);
}

slowDoubleTenTimes(3, function(result){
  console.log('The result of slowDoubleTenTimes is ' + result);
});

Logic is telling me that in slowDoubleTenTimes , in the for loop, x should be changing. 逻辑告诉我,在slowDoubleTenTimes ,在for循环中, x应该在变化。 And every time it calls slowDouble again in the subsequent for-loop iteration, x should be different. 并且每次在随后的for循环迭代中再次调用slowDouble时, x都应该不同。 But x remains at 3 ! 但是x仍然是3 In fact, the resulting answer in callback(x) should be 3072 . 实际上,在callback(x)得到的答案应该是3072 Yet, x changes from 3 to 6 and then remains at 6 . 但是, x3变为6 ,然后保持在6

Is there something about JavaScript that I don't know that's preventing the result from changing? 关于JavaScript的某些事情我不知道会阻止结果更改?

Also, the weird thing is, if I put console.log("hi") after the for-loop, the console prints out "hi" before slowDouble runs. 另外,很奇怪的是,如果我将console.log("hi")放在for循环之后,控制台会在slowDouble运行之前打印出“ hi”。 Shouldn't slowDouble run before console.log("hi") ? 不应该slowDoubleconsole.log("hi")之前运行吗? Or is there something about setTimeout that I'm not understanding correctly? 还是关于setTimeout某些事情我没有正确理解?

Thank you! 谢谢!

slowDouble does not block. slowDouble不会阻止。 So, "callback" is invoked right away. 因此,“回调”立即被调用。

setTimeout says, "run this function in 500 milliseconds". setTimeout说,“在500毫秒内运行此功能”。 But, it doesn't block, which means that it continues to the next lines after it registered to be invoked in 500 ms. 但是,它不会阻塞,这意味着它在注册为要在500毫秒内调用后继续到下一行。

  • JavaScript engines only have a single thread, forcing asynchronous events to queue waiting for execution. JavaScript引擎只有一个线程,从而迫使异步事件排队等待执行。

  • If a timer is blocked from immediately executing it will be delayed 如果定时器被阻止立即执行,它将被延迟
    until the next possible point of execution (which will be longer than the desired delay). 直到下一个可能的执行点(将比所需的延迟长)。

http://ejohn.org/blog/how-javascript-timers-work/ http://ejohn.org/blog/how-javascript-timers-work/

function slowDouble(x, callback) {
    setTimeout(function() {
    callback(2 * x);
  }, 500);
}

function slowDoubleTenTimes(x, callback) {
    for (i = 0; i < 10; i++) {
        slowDouble(x, function(result) {
            x = result;
        });
    }

    callback(x);  //This will get called before the callback from timeout
                  // in slowDouble's context is called. 
                  // console.log(3)

}

slowDoubleTenTimes(3, function(result){
  console.log('The result of slowDoubleTenTimes is ' + result);
});

you are immediately calling slowDoubleTenTimes with the x value of 3 which then invokes slowDouble 10 times and every call passes the value of x as 3 . 您立即调用slowDoubleTenTimesx的值3 ,其然后调用slowDouble 10倍,每个呼叫传递的值x3 approximately 500 ms later your callback is invoked to change the value of x and since the other calls to slowDouble have already been invoked, changing the value of x has no effect on those calls. 大约500毫秒后,将调用您的回调以更改x的值,并且由于已经调用了slowDouble的其他调用,因此更改x的值对这些调用无效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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