2014-12-28 75 views
2

我正在爲要在瀏覽器中運行的元語言編寫解析器。元語言是阻塞的,但由於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

無條件轉到只是一個while循環 – akonsu

+0

你如何解釋一個非阻塞語言中的阻塞while循環? – twinlakes

+0

我不明白這個問題。 – akonsu

回答

1

使用yield讓你可以暫停功能,然後regenerator在舊的瀏覽器中運行它:

首先,我們把dosomething(4)在你的語言爲:

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

注意節點ERR-回約定 - 回調函數有兩個參數 - 第一個是錯誤,第二個是返回值。

那麼 - 你可以將它們轉換爲承諾容易:

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

現在,當他們返回promises-你可以換行與yield S:

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

您將需要調用addYieldHandler在爲了處理產生的非諾言價值。這將在開始下一步之前「同步」執行,以等待每個承諾解決。最後使用再生器將代碼轉換爲ES5瀏覽器可以運行的東西(因爲yield只能在FF和Chrome中的atm標誌下運行)。