我是网络开发的新手。来自Delphi / pascal。我的长期目标是将遗留应用程序转换为Web环境。 (我正在使用此应用程序:http://smartmobilestudio.com/将pascal交叉编译为javascript,但这不应该影响这个问题)。我的旧程序使用同步远程过程调用(RPC' s)到服务器。我使用名为EWD.js(http://robtweed.wordpress.com/2014/01/23/ewd-js-on-fhir/comment-page-1/)的技术,通过node.js进行异步调用。我在这里读了很多关于同步和同步调用的帖子。如果我不能让EWD以同步的方式行事,我担心我只是运气不好。但我想更好地理解这一点。
考虑这个伪代码:
RPCcall
//business logic
RPCCall
//business logic
RPCCall
//business logic.
如果任何RPC调用失败,则整个应用程序应该失败。我已经阅读了" continuation样式"中的编码,我认为每个异步调用都会告诉在完成后通过onMessage处理程序在收到返回消息时调用回调函数来获取补丁:
MyProc()
RPCCall(<name>,MyProc_2);
end;
MyProc2()
//business logic
RPCCall(<name, MyProc_3);
end;
MyProc3()
//business logic
RPCCall(<name, MyProc_3);
end.
这是可能的,虽然尴尬/丑陋。但是这样的情况呢?
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
我没有真实地看到如何将上述内容转换为延续风格。如果在逻辑树或循环中间有一个调用,我怎么能跳回到那个状态?以前怎么做过的?完全重新编码遗留应用程序是不现实的。它非常庞大而复杂。
任何帮助将不胜感激。 感谢
答案 0 :(得分: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) { })
...
})
我希望这会有所帮助。
答案 1 :(得分:2)
正如tik27已经说过,最常见的解决方案是使用延迟对象。
您可以从某些框架/库中获取它们或编写自己的框架/库。 我认为最简单的方法是使用jQuery延迟,你可以找到nodejs的内容 在这里(What nodejs library is most like jQuery's deferreds?)。
简而言之:
让我们假设
然后解决方案看起来像这样:
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
}
});
使用大多数现有延迟对象中的方法链接 您可以使这些代码看起来几乎像是同步的。
答案 2 :(得分:1)
我希望我理解你:
你有一个weblient与ewdRESTServer交谈, ewdRESTServer正在与EWDServer交谈, EWDServer正在与你的遗留后端交谈? 你想从你的EWDServer到你的传统后端进行一系列rpc调用吗?
你应该像async.js这样的lib,你可以传递一个错误处理函数作为参数