Javascript将异步转换为同步
我是网络开发新手。来自Delphi/pascal。我的长期目标是将遗留应用程序转换为web环境。(我正在使用这个应用程序:将pascal交叉编译为javascript,但这不会影响这个问题)。我的遗留程序使用对服务器的同步远程过程调用(RPC)。我正在使用一种名为EWD.js()的技术,它通过node.js进行异步调用。我在这里读过很多关于同步调用与同步调用的文章。我担心如果我不能让EWD以同步的方式行动,那我就是运气不佳。但我想更好地理解这一点 考虑以下伪代码:Javascript将异步转换为同步,javascript,synchronous,legacy,Javascript,Synchronous,Legacy,我是网络开发新手。来自Delphi/pascal。我的长期目标是将遗留应用程序转换为web环境。(我正在使用这个应用程序:将pascal交叉编译为javascript,但这不会影响这个问题)。我的遗留程序使用对服务器的同步远程过程调用(RPC)。我正在使用一种名为EWD.js()的技术,它通过node.js进行异步调用。我在这里读过很多关于同步调用与同步调用的文章。我担心如果我不能让EWD以同步的方式行动,那我就是运气不佳。但我想更好地理解这一点 考虑以下伪代码: RPCcall //busin
RPCcall
//business logic
RPCCall
//business logic
RPCCall
//business logic.
如果任何RPC调用失败,那么整个应用程序都应该失败。我读过“延续风格”的编码,我认为每个异步调用都会通过让onMessage处理程序在收到返回消息时调用回调函数来告诉完成后从何处获取补丁:
MyProc()
RPCCall(<name>,MyProc_2);
end;
MyProc2()
//business logic
RPCCall(<name, MyProc_3);
end;
MyProc3()
//business logic
RPCCall(<name, MyProc_3);
end.
我不知道如何将上面的样式转换为延续样式。如果在逻辑树或循环中间有一个调用,我如何跳回该状态?以前是怎么做到的?完全重新编码遗留应用程序是不现实的。它非常大,非常复杂
任何帮助都将不胜感激。
谢谢您可能希望使用AJAX和jQuery。有一个参数确保它发送同步调用,而不是普通的异步调用 它看起来像这样:
if(/*condition*/) {
function RPCCall() {
return $.ajax({
type: "GET",
url: remote_url,
async: false
}).responseText;
}
//business logic
}
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) {
...
})
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
}
});
如果您真的不想使用AJAX,而使用nodejs,您可以这样做:
if(/*condition*/) {
function RPCCall() {
return $.ajax({
type: "GET",
url: remote_url,
async: false
}).responseText;
}
//business logic
}
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) {
...
})
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
}
});
如果您需要传递一个范围,您可以这样做
.then(function(next, d) {
http.get({}, function(res) {
next(res, d);
});
})
.then(function(next, res, d) { })
...
})
我希望这会有所帮助。正如tik27所说,最常见的解决方案是使用延迟对象 您可以从一些框架/库中获取它们,也可以自己编写。 我认为最简单的方法是使用jQuery延迟,您可以找到与nodejs相关的内容 这里() 简而言之:
- 我们有一个“Deferred()”延迟对象构造函数
- 延迟对象具有方法“done”,该方法附加了一个回调,如果满足条件,将调用该回调
- 延迟对象具有方法“fail”,该方法附加一个回调,如果 不符合条件
- 延迟对象具有方法“resolve”,表示条件已满足
- 延迟对象具有方法“拒绝”,表示条件尚未满足
- 传递给“resolve”的参数被传播到“done”-回调
- 传递给“reject”的参数被传播到“fail”-回调
if(/*condition*/) {
function RPCCall() {
return $.ajax({
type: "GET",
url: remote_url,
async: false
}).responseText;
}
//business logic
}
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) {
...
})
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
}
});
var conditionA=new Deferred();
RPCcall(“rpccall1”,函数(结果){
//确定条件A状态的业务逻辑
如果(某物){
条件a.resolve();
}否则{
条件a.拒绝();
}
});
条件a.done(函数(){
//条件B和以下业务逻辑的RPCcall
});
条件A.失败(函数(){
var条件=[];
对于(变量i=0;i<10;i++){
条件[i]=新的延期付款();
//相应的RPCcall和回调设置
//我希望你能明白
}
});
通过使用在大多数现有延迟对象中存在的方法链接
实现您可以使此代码看起来几乎像是同步的。我希望我正确理解您的意思: 您有一个Web客户端正在与EWDREST服务器通信, EWDREST服务器正在与EWDServer对话, EWDServer正在与您的旧后端对话? 是否要从EWDServer到旧版后端进行rpc调用链 您应该创建一个类似async.js的库,您可以将错误处理函数作为参数传递 看一看:
我将研究javascripts延迟/承诺功能,它允许您链接异步调用。为了简单的解决方案,您不能让
RPCcall
ajax同步吗?@tik27--我将对此进行检查。谢谢@Bergi——我认为让同步呼叫工作是最好的选择。然而,我需要使用EWD,因为它连接到我的传统腮腺炎数据库。Rob Tweed有几种不同的EWD技术。我不认为我在使用ewdrest服务器的东西。我包含了一个连接到node.js的EWD.js库,该库反过来执行服务器端js,该js可以连接到我的旧腮腺炎数据库。@Nekiy--这是一个经过深思熟虑的回答,我对此表示感谢。但是伙计,这让我头疼。我将有>100k行的遗留代码。我无法将所有逻辑分离出来,并将其更改为共享对象。但如果我有新的编码,我会记住你的技术。谢谢