首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将异步转换为同步的Javascript

将异步转换为同步的Javascript
EN

Stack Overflow用户
提问于 2014-04-07 12:07:18
回答 3查看 769关注 0票数 4

我对网络开发很陌生。来自德尔福/帕斯卡。我的长期目标是将遗留应用程序转换为web环境。(我使用这个应用程序:http://smartmobilestudio.com/交叉编译pascal到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调用失败,那么整个应用程序就会失败。我读过以“延续方式”编写代码的文章,我认为每个异步调用都会通过让onMessage处理程序在收到返回消息时调用回调函数来告诉在完成时在哪里获取修补程序:

代码语言:javascript
复制
MyProc()
  RPCCall(<name>,MyProc_2);
end;

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

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

这是有可能的,虽然尴尬/丑陋。但是像这样的情况呢?

代码语言:javascript
复制
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

实际上,我看不出如何将上面的样式转换为延续风格。如果在逻辑树或循环的中间有一个调用,我如何才能跳回这种状态?以前是怎么做到的?完全重新编码遗留应用程序是不现实的。它非常大,很复杂。

任何帮助都将不胜感激。谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-04-07 13:53:11

您可能希望与jQuery一起使用AJAX。有一个参数来确保它发送同步调用,而不是普通的异步调用。

看起来会是这样的:

代码语言:javascript
复制
if(/*condition*/) {

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

如果您真的不想使用AJAX,并且使用nodejs,您可以这样做:

代码语言:javascript
复制
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) {
    ...
  })

如果您需要传递一个范围,您可以这样做。

代码语言:javascript
复制
  .then(function(next, d) {
    http.get({}, function(res) {
      next(res, d);
    });
  })
  .then(function(next, res, d) { })
    ...
  })

我希望这会有所帮助。

票数 3
EN

Stack Overflow用户

发布于 2014-04-07 14:07:03

正如tik27已经说过的,最常见的解决方案是使用延迟对象。

您可以从某个框架/库中获取它们,或者编写自己的框架/库。我认为最简单的方法是使用jQuery延迟,您可以在这里找到nodejs (What nodejs library is most like jQuery's deferreds?)的特性。

简而言之,这个想法:

  1. 您创建了一个共享对象,该对象表示某种状态未知的条件,但您将不知何故知道它在未来某个地方的状态
  2. 在这个对象上附加一些回调:如果满足条件,应该调用的回调;如果条件不满足,则应该调用的回调。
  3. 这个共享对象具有向条件状态发出信号的方法,因此在某个时候,您可以使用它们来指示条件是否满足,此时延迟对象相应地调用附加回调。

让我们假设

  • 我们有一个“延迟()”延迟对象构造函数,
  • 递延对象具有“完成”方法,该方法附加回调,如果满足条件,回调将被调用。
  • 延迟对象具有"fail“方法,该方法附加回调,如果不满足条件,回调将被调用。
  • 延迟对象有“解决”方法,表示已满足条件。
  • 延迟对象有“拒绝”方法,表示没有满足条件
  • 传递给“解决”的参数被传播到“完成”-callbacks
  • 传递给“拒绝”的参数被传播到"fail"-callbacks

那么解决方案可以是这样的:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2014-04-07 14:12:56

我希望我能正确地理解你:

您有一个weblient与一个ewdRESTServer对话,ewdRESTServer正在与一个EWDServer对话,EWDServer正在与您的遗留后端对话?您想要从EWDServer到遗留后端进行一系列rpc调用吗?

您应该像async.js这样的库,您可以传递一个错误处理函数作为参数。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22911971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档