让我们以此为例:
function test(i, total) {
return total + i * 100 / 999 * -124 / 333;
}
var total = 0;
for (var i = 0; i <= 100; i++) {
total = test(i, total);
console.log(total);
}
测试时,我看到它同步工作 - for循环将等到test(i,total)返回其值之后再进行下一次迭代。
然而,在功能完成其功能之前,还有其他情况下循环会继续进行甚至完成。如果测试函数需要3秒才能返回,为什么循环等待呢?是因为测试函数中没有任何异步性质吗?我尝试在测试函数中设置3秒的setTimeout,然后从控制台日志中获取未定义。
答案 0 :(得分:1)
函数调用在Javascript中是同步和单线程的。这是根据语言设计。当你从循环中调用test
函数时,循环会一直等到函数返回。
当您致电setTimeout
时,会创建计时器并立即返回。它不会等待计时器被触发(即使是第一次)。 timer 是异步触发的。
有关详细信息,请参阅Is JavaScript guaranteed to be single-threaded?并阅读web workers。
答案 1 :(得分:1)
&#34;如果测试函数需要3秒钟才能返回,为什么循环会等待 在那?是因为测试中没有任何异步性质 起作用&#34;
完全。函数的执行在Javascript中是同步的,就像几乎所有其他语言一样。执行是在一个路径上完成的,所以当你调用一个函数时它将在返回之前完成,并且调用之后的代码可以继续。
如果在函数中使用异步代码(例如使用setTimeout
),则异步代码将被暂停,直到其余代码执行完毕并且浏览器恢复控制,因为Javascript是单线程。
如果你在循环中调用test
101次并且每次都使用setTimeout
,那么在循环完成时会有101段代码等待运行。这些101段代码直到循环完成后才能运行。您保留的代码无法提供从函数返回的值,因为函数在代码运行之前返回。
要异步运行代码,您将使用在函数完成时调用的回调。例如:
function test(i, callback) {
window.setTimeout(function(){
var result = i * 100 / 999 * -124 / 333;
callback(result);
}, 1000);
}
var total = 0;
var resultCount = 0;
for (var i = 0; i <= 100; i++) {
test(i, handleCallback);
}
function handleCallback(value) {
total += value;
resultCount++;
if (resultCount == 101) {
console.log(total);
}
}
答案 2 :(得分:0)
这是因为JavaScript是单线程的。您的代码是单线程的。