2010-05-07 126 views
0

假設您有一個調用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; } 
); 

回答

2

由於您使用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); 
    } 
}); 
1

從本質上講,你不能,但你可以打破該功能分爲「之前」和「之後」的部分,就像這樣:

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來提供回調,並期望結果以這種方式提供,而不是作爲返回值。

1

那麼你試圖完成的是模擬sleep命令,所以你的腳本「等待」你的AJAX請求?但這並不合情理。這就是爲什麼你必須首先回調,一旦請求已經回覆,繼續流程,因爲你無法預測它的響應時間。

1

不要陳述,但不能從異步創建同步,只能以其他方式創建。您需要設計自己的代碼以支持這一點,這通常意味着通過您的呼叫鏈完成回調。

有一個特殊的異常,就是你可以在原始XMLHttpRequest的'open'方法的異步參數中指定'false',這將導致send方法阻塞,直到它完成。但是這可能與某些框架不兼容,並且非常不靈活。大多數JS的東西是異步的。

0

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

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

1

你不應該這樣做。從回調的角度繼續處理。 你的風險完全掛在瀏覽器如果呼叫不返回。

如果你控制了服務器端,那麼你可以寫在JS側一些代碼來調用聚集,然後寫在服務器端的東西來解壓,做從集合體中各嵌套調用多個呼叫。當迴應回來然後聚合那些並且送回他們。這將節省性能,因爲大量呼叫比許多小呼叫便宜。

我們這樣做的一個項目我的工作和它的工作非常漂亮。它還整合在JS端邏輯不被星羅棋佈,由於所有的異步回調。