【问题标题】:Does setInterval wait for the action inside if it is blocking?如果 setInterval 阻塞,它会等待里面的动作吗?
【发布时间】:2021-08-05 05:40:48
【问题描述】:

您好,我有如下功能

let schedule = setInterval(() => {
    result = execSync(command).toString()
}, 2000)
  1. 如果 execSync 需要超过 2000 来解决,setInterval 是否仍会重复或将通过 同步execSync 将使 setInterval 等待它首先完成

【问题讨论】:

    标签: node.js electron child-process


    【解决方案1】:

    两者兼而有之:

    如果execSync 需要 2000 毫秒,则意味着在这 2 秒内没有其他代码会运行。毕竟,JavaScript 是单线程的,而您正在阻塞该线程。

    execSync 完成后(函数调用完成),事件循环继续。由于距离上一次发生间隔已经过去了 2 秒,所以下一次调用几乎会立即发生。

    您可以自己快速验证这一点(例如在 REPL 中):

    execSync = require('child_process').execSync;
    setInterval(() => { console.log('a', Date.now()); execSync('sleep 2'); console.log('b', Date.now()); }, 2000);
    

    另外有趣的是:如果您改为睡 5 秒,结果将是相同的(如果您忽略冻结时间更长)。例如,execSync 完成后,它不会突然同时触发两个任务。验证:

    execSync = require('child_process').execSync;
    i = 0;
    setInterval(() => { console.log('a', Date.now()); if (i++ > 5) return; execSync('sleep 5'); console.log('b', Date.now()); }, 2000)
    

    【讨论】:

    • 您好,感谢您的澄清,我问是因为我的电子应用程序总是冻结(没有响应)所以我认为 setInterval() 在命令需要很长时间时执行了多次但现在不是在这种情况下,我将其重写为使用 setTimeOut() 并异步执行命令以确保命令首先完成并且不再冻结,您是否知道为什么它在第一种情况下使用 setInterval 冻结?是不是因为它阻塞了线程而Window认为这是一个问题?
    • 就像在浏览器中一样(无论是在执行无限循环还是只是使用例如断点暂停 JS 时),冻结会阻止您与站点交互。在 Electron“服务器端”上执行此操作可能如果是渲染过程,甚至会冻结整个窗口,我真的不知道 Electron 内部是如何工作的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-14
    • 2022-01-04
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多