将回调信息返回到原始调用函数

问题描述:

假设您有一个调用Web服务方法的Javascript函数。这样web服务就完成并调用一个回调函数,结果就是这样。将回调信息返回到原始调用函数

如何将结果返回到调用Web服务方法的原始函数中?基本上,我试图“同步”异步调用。

更新:

这就是我想要做的事。我正在验证基于Web服务的返回值。

$.validator.addMethod("zzz", 
    function(value, element) { 

     // Call web service function using ASP.NET Ajax. 
     // Get callback value to determine validity. 

     return this.optional(element) || ***return t/f based on validity***; 
    }, 
    function(value, element) { return msg; } 
); 

所以我想我能做到这一点,而不是:

$.validator.addMethod("zzz", 
    function(value, element) { 

     $.ajax({ 
       async: false 
       url: **** web service url **** 
       success: set t/f to validity var 
     }); 

     return this.optional(element) || ***return t/f based on validity var***; 
    }, 
    function(value, element) { return msg; } 
); 

由于您使用jQuery,您可以使用async:false in your ajax command,像这样:

$.ajax({ 
    //options.. 
    async: false 
}); 
//this code will run after the request returns 

注意的是,这个块的UI(锁定了浏览器),最好是继续依赖于工作导致success回调,像这样:

$.ajax({ 
    //options.. 
    success: function(data) { 
    doSomethingWithResult(data); 
    } 
}); 

从本质上讲,你不能,但你可以打破该功能分为“之前”和“之后”的部分,就像这样:

function foo(a) { 
    var b, c; 

    // == The "before" part: 

    b = /* ... */; 

    // == Call the service: 

    callWebService(a, b, callback); 

    // == The "after" part is contained within the callback: 

    function callback(d) { 
     // Do something with a, b, c, and d 
    } 
} 

但要注意的是foo将返回前callback被称为是很重要的。没有办法通过异步调用来阻止它,所以如果你想让函数返回一些东西,你必须重构(或者使用同步调用,但这是一个非常糟糕的主意)。重构将涉及任何调用foo来提供回调,并期望结果以这种方式提供,而不是作为返回值。

那么你试图完成的是模拟sleep命令,所以你的脚本“等待”你的AJAX请求?但这并不合情理。这就是为什么你必须首先回调,一旦请求已经回复,继续流程,因为你无法预测它的响应时间。

不要陈述,但不能从异步创建同步,只能以其他方式创建。您需要设计自己的代码以支持这一点,这通常意味着通过您的呼叫链完成回调。

有一个特殊的异常,就是你可以在原始XMLHttpRequest的'open'方法的异步参数中指定'false',这将导致send方法阻塞,直到它完成。但是这可能与某些框架不兼容,并且非常不灵活。大多数JS的东西是异步的。

我能想到的唯一的办法就是像

function b(){ 
    var a = null; 
    $.get("abc.json", { 
     success: function(data){ 
      a = data; 
     } 
    }); 
    while(a == null){} 
    alert(a); 
} 
b(); 

但通常这是不好的,可能会导致浏览器抱怨脚本的时间太长完成。

+1

除了这个事实,这将保证在地狱你的位置,你应该要么'了'在第一未定义或具有辅助变种来检查,因为回调响应可能仍然是'null'和循环永远不会结束。 – treznik 2010-05-07 14:46:02

+0

绝对。我应该补充说,这个代码不应该用于任何有用的产品。我只是为了理论目的而写它。 – coolnalu 2010-05-07 14:49:26

+0

除了作为一个*非常糟糕的主意*,这甚至不工作。在浏览器的JavaScript是*单线程*(目前,网络工作者线程来了)。这意味着虽然GET将完成,并且浏览器的Javascript解释器将排队成功回调,因为你有唯一的线程绑定在CPU烧写的忙循环中,该回调将永远不会执行,并且循环将永远不会结束。此外,如果请求需要一段时间,你会得到可怕的“这个脚本需要太长时间”的消息(在IE上它是基于操作的,而不是基于时间的;即使IE应该忙 - 等待相当快)。 – 2010-05-08 13:09:08

你不应该这样做。从回调的角度继续处理。 你的风险完全挂在浏览器如果呼叫不返回。

如果你控制了服务器端,那么你可以写在JS侧一些代码来调用聚集,然后写在服务器端的东西来解压,做从集合体中各嵌套调用多个呼叫。当回应回来然后聚合那些并且送回他们。这将节省性能,因为大量呼叫比许多小呼叫便宜。

我们这样做的一个项目我的工作和它的工作非常漂亮。它还整合在JS端逻辑不被星罗棋布,由于所有的异步回调。