2

我是 JavaScript 的初学者,我已经尝试解决这个问题至少两个小时。如果有人可以向我解释为什么会这样,那就太好了!

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

逻辑告诉我 in slowDoubleTenTimes,在 for 循环中,x应该改变。并且每次slowDouble在后续的for循环迭代中再次调用, x都应该不同。但x仍然在3!事实上,得到的答案callback(x)应该是3072。然而,x3变为6,然后保持在6

JavaScript 有什么我不知道的东西会阻止结果发生变化吗?

另外,奇怪的是,如果我放在for 循环之后,控制台会在运行console.log("hi")前打印出“hi” 。slowDouble之前不应该slowDoubleconsole.log("hi")吗?或者有什么setTimeout我没有正确理解的地方?

谢谢!

4

3 回答 3

0

您立即slowDoubleTenTimes使用其x3调用,然后调用slowDouble10 次,每次调用都传递xas的值3。大约 500 毫秒后,您的回调被调用以更改 的值,x并且由于slowDouble已经调用了其他调用,因此更改 的值x对这些调用没有影响。

于 2013-08-10T05:20:04.593 回答
0

slowDouble 不会阻塞。因此,立即调用“回调”。

setTimeout 说,“在 500 毫秒内运行这个函数”。但是,它不会阻塞,这意味着它在注册后会在 500 毫秒内被调用,然后继续执行下一行。

于 2013-08-10T04:54:37.727 回答
0
  • JavaScript 引擎只有一个线程,强制异步事件排队等待执行。

  • 如果计时器被阻止立即执行,它将被延迟
    到下一个可能的执行点(这将比所需的延迟更长)。

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);
});
于 2013-08-10T05:03:13.737 回答