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

Programmatically convert synchronous code to asynchronous code

本文关键字:代码 转换 异步 同步 编程 方式      更新时间:2023-09-26

我正在为要在浏览器中运行的元语言编写解析器。 元语言是阻塞的,但由于 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。 任何帮助,不胜感激。

正如其他人所说,请查看承诺。本教程确实帮助我开始使用它们,希望它也对您有所帮助。https://spring.io/understanding/javascript-promises

使用yield制作可以暂停的函数,然后重新生成以在旧版浏览器中运行它:

首先,我们将您语言的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 来处理生成的非承诺值。这将"同步"执行它们,等待每个承诺解析,然后再开始下一个承诺。最后使用再生器将您的代码转换为 ES5 浏览器可以运行的内容(因为 yield 仅适用于 FF 和 Chrome 中的标志 atm)。