简体   繁体   English

以编程方式将同步代码转换为异步代码

[英]Programmatically convert synchronous code to asynchronous code

I am writing a parser for a metalanguage to be run in the browser. 我正在为要在浏览器中运行的元语言编写解析器。 The metalanguage is blocking, but needs to be converted to nonblocking in the interpreter due to the limitations of javascript. 元语言正在阻止,但由于JavaScript的限制,需要在解释器中将其转换为非阻止。

For example, the metalanguage code might look something like 例如,元语言代码可能看起来像

1. dosomething(4)
2. dosomethingelse(1)
3. dosomething(7)
4. goto 2

with the functions implemented in javascript as 与在javascript中实现的功能一样

function dosomething(n, callback) {
  ... // do something with n
  setTimeout(callback, 1000);
}

function dosomethingelse(n, callback) {
  ... // do something else with n
  setTimeout(callback, 1000);
}

Without the goto statements, this would be easy to compile to javascript and then eval . 如果没有goto语句,这将很容易编译为javascript,然后编译为eval However, I have no clue how to implement the goto s. 但是,我不知道如何实现goto Any help is appreciated. 任何帮助表示赞赏。

As others have said, check out Promises. 正如其他人所说,请查看Promises。 This tutorial really helped me out for getting started with them, hopefully it helps you too. 本教程确实帮助我入门,希望对您有所帮助。 https://spring.io/understanding/javascript-promises https://spring.io/understanding/javascript-promises

Use yield to make functions you can pause and then regenerator to run it in older browsers: 使用yield使您可以暂停的函数,然后重新生成以在较旧的浏览器中运行它:

First, we convert dosomething(4) in your language into: 首先,我们将您的语言中的dosomething(4)转换为:

function doSomething(n, callback){
    setTimeout(function(){ callback(null,true); }, n);
}

Note the node err-back convention - callbacks take two arguments - the first is an error and the second is the return value. 注意节点的err-back约定-回调带有两个参数-第一个是错误,第二个是返回值。

Then - you can convert them to promises easily: 然后-您可以轻松地将它们转换为承诺:

var doSomething = Promise.promisify(doSomething); // using bluebird.

Now, when they return promises- you can wrap lines with yield s: 现在,当它们返回promises时,您可以使用yield s包装行:

Promise.coroutine(function*(){ 
    yield dosomething(4);
    yield dosomethingelse(1);
    yield dosomething(7);
});

You will need to call addYieldHandler in order to deal with yielded non-promise values. 您将需要调用addYieldHandler来处理产生的非承诺值。 This will execute them "synchronously" waiting for each promise to resolve before starting the next. 这将“同步”执行它们,等待每个诺言解决,然后再开始下一个诺言。 Finally use regenerator to convert your code into something ES5 browsers can run (Since yield only works in FF and in Chrome under a flag atm). 最后,使用再生器将您的代码转换为可以运行ES5浏览器的代码(因为yield仅在FF和Chrome中的atm标志下有效)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM