如何将较旧的(非事件驱动的)软件移植到 javascript

How to port older (not event driven) software to javascript

我想将一些旧软件移植到 javascript。这些程序通常不是事件驱动的,只是循环运行。他们只是暂停以从输入流中获取输入。我不能只将它们转换为 javascript,因为经典的 pascal 或 c 读取指令没有等效项。我认为可以使用将触发 onchange 事件的输入字段。然后我的程序将暂停,直到事件触发。但是显然你不能挂起一个JS程序。

我的第二次尝试是在 onchange 事件上设置一个标志。我的程序一直处于循环状态,直到设置标志,然后读取输入字段的值。但是为了防止浏览器被这个循环阻塞,我需要在两次轮询之间使用一些睡眠功能。显然在 JS 中没有等价的睡眠函数。

如何做到这一点?

如果您使用的语言具有类似...

while(true) {
  x = readInput();
  processInput(x);
}

那么你是对的,在 JavaScript 中没有直接的等价物。您需要忘记循环,而是想一想循环中发生的所有事情 before 它阻止用户输入作为设置事件的一部分,以及发生的所有事情 after 作为处理该事件的 回调

上面的(非常琐碎的)程序将在 JavaScript 中重写为:

readInput().then((x) => { processInput(x) });

您可以使用 Promise 和 await/async 来创建类似于您从阻塞代码中了解到的代码。

但需要注意的是,这是不是阻塞代码。在await处,其他等待执行的代码可以交错。

function waitForIntput(id) {
  // create a Promise that resolves at the input event
  return new Promise((resolve, reject) => {
    let elm = document.getElementById(id)

    function listener(evt) {
       // remove the listener so that no memory leaking occures
       elm.removeEventListener('input', listener)

       // resolve the promise with the current value of the element
       resolve(elm.value)
    }

    // call the listener on the input event
    elm.addEventListener('input', listener, false);
  })

}

(async function() {
  while(true) {
     console.log('before waitForIntput')
     console.log(await waitForIntput('test'))
     console.log('after waitForIntput')
  }
}())
<input id="test">

是否以这种方式解决问题取决于具体的用例。一般来说,你应该检查你要执行的任务在新环境中应该如何解决,而不是将旧的风格强加到新环境中。