我正在编写一个解析器,用于在浏览器中运行元语言。元语言是阻塞的,但由于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
。任何帮助表示赞赏。
答案 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中)。