为什么我的同步代码是异步执行的?
Why is my synchronous code executing asynchronously?
我正在尝试 运行 一些同步函数,它应该等待一定时间然后 return 控制。但出于某种原因,它一直异步执行,或者至少看起来是这样。
这是代码:
function pause(ms) {
var dt = new Date();
while (new Date() - dt <= ms) {
/* Do nothing */
}
}
console.log("start calculation..");
pause(3000);
console.log("calculation finished!");
这会立即在控制台中显示以下内容:
start calculation..
calculation finished!
完全没有延迟,好像暂停函数是异步执行的
我试过3种不同版本的暂停功能,都没什么区别。
你可以在sandbox我放代码的地方看到这个
(您必须转到首选项 - sandbox.config.json 并打开“无限循环保护”才能工作)
- 为什么代码 运行 不同步,首先显示“开始计算...”消息,然后在延迟 3 秒后显示第二条消息?
- 是否有更好的方法来模拟 运行 耗时的同步函数?
由于我的问题只得到部分回答,我会自己提供解决方案,以防其他人遇到类似问题:
首先,此代码现在可以在 Chrome、Chromium 和 Firefox 的控制台中正常运行。以前没有,所以也许在这方面对 javascript 引擎进行了升级。
运行 虽然提供的 CodeSandbox 中的代码在延迟 3 秒后仍会同时记录两行。
正如人们所指出的,有两件事可能是造成这种情况的原因:
- 编译器删除空循环
- 只要循环 运行
,控制台消息就不会刷新
此代码将解决这两个问题:
function pause(ms, start=new Date()) {
while (new Date() - start <= ms) {
setTimeout(()=>pause(ms,start))
}
}
console.log("start calculation..");
pause(3000);
console.log("calculation finished!");
在允许执行事件回调之后,调用 SetTimeout(即使延迟为 0 毫秒)将导致其余代码执行(递归函数调用)返回到事件循环以供稍后处理第一的。这确保其他事件 - 例如控制台的日志记录 - 不会被阻止。
它还在循环中放置了一些实际代码,这样循环就不会被任何编译器代码优化删除。
我正在尝试 运行 一些同步函数,它应该等待一定时间然后 return 控制。但出于某种原因,它一直异步执行,或者至少看起来是这样。
这是代码:
function pause(ms) {
var dt = new Date();
while (new Date() - dt <= ms) {
/* Do nothing */
}
}
console.log("start calculation..");
pause(3000);
console.log("calculation finished!");
这会立即在控制台中显示以下内容:
start calculation..
calculation finished!
完全没有延迟,好像暂停函数是异步执行的
我试过3种不同版本的暂停功能,都没什么区别。
你可以在sandbox我放代码的地方看到这个
(您必须转到首选项 - sandbox.config.json 并打开“无限循环保护”才能工作)
- 为什么代码 运行 不同步,首先显示“开始计算...”消息,然后在延迟 3 秒后显示第二条消息?
- 是否有更好的方法来模拟 运行 耗时的同步函数?
由于我的问题只得到部分回答,我会自己提供解决方案,以防其他人遇到类似问题:
首先,此代码现在可以在 Chrome、Chromium 和 Firefox 的控制台中正常运行。以前没有,所以也许在这方面对 javascript 引擎进行了升级。 运行 虽然提供的 CodeSandbox 中的代码在延迟 3 秒后仍会同时记录两行。
正如人们所指出的,有两件事可能是造成这种情况的原因:
- 编译器删除空循环
- 只要循环 运行 ,控制台消息就不会刷新
此代码将解决这两个问题:
function pause(ms, start=new Date()) {
while (new Date() - start <= ms) {
setTimeout(()=>pause(ms,start))
}
}
console.log("start calculation..");
pause(3000);
console.log("calculation finished!");
在允许执行事件回调之后,调用 SetTimeout(即使延迟为 0 毫秒)将导致其余代码执行(递归函数调用)返回到事件循环以供稍后处理第一的。这确保其他事件 - 例如控制台的日志记录 - 不会被阻止。
它还在循环中放置了一些实际代码,这样循环就不会被任何编译器代码优化删除。