2014-04-07 53 views
4

我是網絡開發新手。來自Delphi/pascal。我的長期目標是將遺留應用程序轉換爲Web環境。 (我正在使用這個應用程序:http://smartmobilestudio.com/交叉編譯爲JavaScript,但不應該影響這個問題)。我的傳統程序使用同步遠程過程調用(RPC)到服務器。我正在使用名爲EWD.js(http://robtweed.wordpress.com/2014/01/23/ewd-js-on-fhir/comment-page-1/)的技術,它通過node.js進行異步調用。我在這裏閱讀了許多關於同步和同步調用的帖子。如果我不能以同步的方式使EWD行動,我擔心我只是運氣不好。但我想更好地理解這一點。Javascript轉換異步到同步

考慮這個僞代碼:

RPCcall 
//business logic 
RPCCall 
//business logic 
RPCCall 
//business logic. 

如果有任何的RPC調用失敗,那麼整個應用程序應該失敗。

MyProc() 
    RPCCall(<name>,MyProc_2); 
end; 

MyProc2() 
    //business logic 
    RPCCall(<name, MyProc_3); 
end; 

MyProc3() 
    //business logic 
    RPCCall(<name, MyProc_3); 
end. 
:我已經在「延續的風格」,這是我採取的是每個異步調用告訴凡具有的onMessage處理程序在收到返回消息調用回調函數拿起完成後,該補丁讀取編碼

這將是可能的,雖然尷尬/醜陋。但是這樣的情況呢?

RPCcall 
//business logic 
if conditionA then begin 
    if conditionA2 then begin 
    RPCCall 
    //business logic 
    end else 
    RPCCall 
    //business logic 
    end else begin 
    for i=1 to 10 do begin 
     RPCCall 
     //business logic 
    end; 
    end 
end 

我現在看不出如何將上述轉換爲延續風格。如果在邏輯樹或循環中間有一個呼叫,我該如何跳回到該狀態?這是如何做到的?完全重新編碼遺留應用程序是不現實的。這是非常非常大和複雜。

任何幫助將不勝感激。 謝謝

+2

我會考慮推遲/許JavaScript的功能,它可以讓你鏈式異步調用。 – tik27

+1

爲了一個簡單的解決方案,你不能讓'RPCcall' ajax同步嗎? – Bergi

+0

@ tik27 - 我會檢查一下。謝謝! – kdtop

回答

3

您可能想要使用AJAX和jQuery。有一個參數可以確保它發送同步調用,而不是正常的異步調用。

這將是這個樣子:

if(/*condition*/) { 

function RPCCall() { 
    return $.ajax({ 
     type: "GET", 
     url: remote_url, 
     async: false 
    }).responseText; 
} 
    //business logic 
} 

如果你真的不想使用AJAX,並使用你的NodeJS可以做這樣的事情:如果你需要

var sequence = Futures.sequence(); 

sequence 
    .then(function(next) { 
    http.get({}, next); 
    }) 
    .then(function(next, res) { 
    res.on("data", next); 
    }) 
    .then(function(next, d) { 
    http.get({}, next); 
    }) 
    .then(function(next, res) { 
    ... 
    }) 

通過一個範圍,你可以做這樣的事情。

.then(function(next, d) { 
    http.get({}, function(res) { 
     next(res, d); 
    }); 
    }) 
    .then(function(next, res, d) { }) 
    ... 
    }) 

我希望這會有所幫助。

2

由於tik27已經說過最常見的解決方案是使用延遲對象。

您可以從某個框架/庫中獲取它們或編寫自己的。 我認爲最簡單的方法是使用jQuery延遲,你可以在這裏找到nodejs (What nodejs library is most like jQuery's deferreds?)。

中,這一觀念:

  1. 您創建一個共享對象,表示未知狀態, 一些條件,但你會莫名其妙地知道它的地方,就是在未來
  2. 狀態你附加一些回調到該對象: 如果這些條件得到滿足應對其調用那些 如果條件不滿足,應對其調用
  3. 此共享對象有方法在某些時候,你的信號的狀況的狀態,所以我們 e他們發信號表示該條件已滿足,此時延遲對象相應調用附加回調。

讓我們假設

  • 我們有一個「延遲()」遞延對象的構造函數,
  • 延遲對象有方法「做」的重視,如果條件滿足
  • 將被調用的回調
  • 延遲對象的方法「失敗」,附加一個回調,如果不符合 條件,將會調用回調
  • 延遲對象具有方法「resolve」,表示已滿足條件的信號
  • 延遲對象有方法「拒絕」這標誌着條件沒有帶滿足
  • 傳遞給「解決」傳播到「做」的論點-callbacks
  • 傳遞到「拒絕」被傳播到參數「失敗」 -callbacks

那麼解決方案可能是這個樣子:

var conditionA = new Deferred(); 
RPCcall("rpccall1", function (result) { 
    //buisness logic that determines state of conditionA 
    if(something) { 
     conditionA.resolve(); 
    } else { 
     conditionA.reject(); 
    } 
}); 
conditionA.done(function() { 
    // RPCcall for conditionB and following business logic 
}); 
conditionA.fail(function() { 
    var conditions = []; 
    for(var i = 0; i < 10; i++) { 
     conditions[i] = new Deferred(); 
     // corresponding RPCcall and callbacks setup 
     // i hope you get the idea 
    } 
}); 

利用方法鏈這是存在於大多數現有的延遲對象 實現中,您可以使此代碼看起來幾乎像是同步的。

+0

@Nekiy - 這是一個非常深思熟慮的答覆,我很感激。但是,男人,它讓我頭痛。我將要有> 100k行的遺留代碼。我無法挑選出所有的邏輯並將其改爲共享對象。但是如果我新編寫新的代碼,我會記住你的技巧。謝謝! – kdtop

1

我希望我理解你的權利:

你有weblient跟一個ewdRESTServer, 的ewdRESTServer在談論到EWDServer, 的EWDServer是說你的遺留後端? 你想從你的EWDServer到你的傳統後端進行一系列rpc呼叫?

你應該你喜歡async.js一個lib,你可以傳遞一個錯誤處理函數作爲參數

看看: How to Handle Errors in Node.js using Express

+0

Rob Tweed有幾種不同的EWD技術。我不認爲我使用ewdRESTserver的東西。我包含一個EWD.js庫,它連接到node.js,後者又執行服務器端js,它可以連接到我的傳統mumps數據庫。 – kdtop