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

时间:2014-12-28 03:27:58

标签: javascript interpreter metalanguage

我正在编写一个解析器,用于在浏览器中运行元语言。元语言是阻塞的,但由于javascript的限制,需要在解释器中转换为非阻塞。

例如,元语言代码可能类似于

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

将函数在javascript中实现为

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

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

如果没有goto语句,这将很容易编译为javascript,然后eval。但是,我不知道如何实现goto。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:2)

正如其他人所说,查看承诺。本教程真的帮助我开始使用它们,希望它也可以帮助你。 https://spring.io/understanding/javascript-promises

答案 1 :(得分:1)

使用yield制作可以暂停的功能,然后regenerator在旧浏览器中运行它:

首先,我们将您语言中的dosomething(4)转换为:

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

注意节点错误回复约定 - 回调有两个参数 - 第一个是错误,第二个是返回值。

然后 - 您可以轻松地将它们转换为承诺:

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

现在,当他们返回承诺时 - 你可以使用yield s换行:

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

您需要致电addYieldHandler以处理已产生的非承诺值。这将同步执行它们"等待每个承诺在开始下一个之前解决。最后使用regenerator将你的代码转换成ES5浏览器可以运行的东西(因为yield仅适用于FF,而且在一个标志atm下的Chrome中)。