【问题标题】:How to port older (not event driven) software to javascript如何将旧的(非事件驱动的)软件移植到 javascript
【发布时间】:2019-07-03 15:12:59
【问题描述】:

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

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

如何做到这一点?

【问题讨论】:

  • JS 已经有一个事件循环。您无需在其上设置另一个。

标签: javascript porting


【解决方案1】:

您可以使用 Promises 和 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">

以这种方式解决它是否是一个好主意取决于确切的用例。一般来说,你应该检查你想要执行的任务在新环境中应该如何解决,而不是把旧的风格强加到新的环境中。

【讨论】:

    【解决方案2】:

    如果您来自一种类似...的语言

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

    那么你是对的,在 JavaScript 中没有直接的等价物。您需要忘记循环,而是将循环中发生的一切之前视为设置事件的一部分,以及之后发生的一切> 作为处理该事件的回调

    上面的(非常简单的)程序将用 JavaScript 重写为:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-11
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-06
      相关资源
      最近更新 更多