2014-10-05 56 views
-2

我的問題很簡單,我認爲很多程序員已經必須面對這個問題。 我使用angularjs和我的JavaScript看起來如下:是否有可能使一個函數不能返回,直到滿足條件?

controller('myController', function()) 
{ 
    if(validateForm()) 
    { 
     //do after-validation stuff 
    } 
    validateForm = function() 
    { 
     var val = undefined; 
     $http.get('api/validate/'). 
     success(function(data){ 
      val = true; 
     }). 
     error(function(data){ 
      val =false; 
     }); 
     while(!val) 
     { // loop over till val has value 
     } 
     return val; 
    } 
} 

我有兩個問題:

1)當我進行HTTP調用它返回一個承諾對象,並將其解析爲成功或錯誤的功能。如果是這種情況,那麼這段代碼中的while循環不應該是無限的,但它是。通過調試,我發現如果我給變量'var'賦值,那麼只有http調用被創建,即當循環結束時。 爲什麼http調用是延遲調用,等待while循環結束? 2)如果我刪除了while循環,不管'var'的值是什麼,函數都會返回。如何定義'var'才能使它返回?

+0

可以請你先描述一下嗎? :) – 2014-10-05 04:22:35

+0

嗨Kalhano Torres Pamuditha,這個場景本身很簡單,我試圖實現的是一個調用B和B返回一個基於哪個A做某事或繼續前進的值。 – sweetcode 2014-10-05 05:18:35

+0

可能重複[如何從Ajax調用返回響應?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) – 2014-10-05 05:26:39

回答

0

那麼通常像這些ajax調用是不同步的,說,當你的while循環被擊中你的變量val尚未設置。你應該做的是,只要在成功或錯誤情況下調用函數,並且該函數應該有你的while循環。或者嘗試做異步ajax調用,我不確定如果可能與選定的方法。所以,你的新代碼將是這樣

function mycallback(someval){ 
    while(!someval) 
    { // loop over till val has value 
    } 
} 
controller('myController', function()) 
{ 
    if(validateForm()) 
    { 
     //do after-validation stuff 
    } 
    function() 
    { 
     var val = undefined; 
     $http.get('api/validate/'). 
     success(function(data){ 
      val = true; 
      mycallback(val); 
     }). 
     error(function(data){ 
      val =false; 
      mycallback(val); 
     }); 


    } 
} 

取決於你的需要,你需要改變流程,以滿足此同步/異步調用。我不建議同步調用,因爲它會讓您的Ajax響應時間延長執行時間。你應該練習只使用異步呼叫。

+0

嗨Sumit ,在這種情況下,if()條件總是不成立? – sweetcode 2014-10-05 05:15:18

+0

嗯,我不知道你爲什麼這麼做,因此我沒有碰它。我想這是驗證其他領域,除了驗證你需要從ajax,如果沒有,然後把它放在回調函數。 – 2014-10-06 10:15:20

1

JavaScript是單線程的,所以http成功/失敗從未得到執行,因爲while循環正在進行。這會導致你的無限循環。

返回承諾並在調用函數中使用它。

+0

如果我向調用函數返回承諾並執行promise.then(...),那麼無論http調用的返回值如何,控件都將繼續前進。因此,在prmosie.then(..)語句之後的任何內容都會被執行,這是我想避免的。我可以把我的整個邏輯放在.then()中,但這會讓事情變得非常混亂。如果(fnCalll())看起來比promise.then()更簡單。 – sweetcode 2014-10-05 05:11:33

+0

OK,添加到http調用中的糖成功和錯誤方法沒有與它們相關的值(即包裝器函數中沒有返回值),所以下一個promise中的值將是未定義的(我不在電腦,所以這可能不正確)。要麼跳過糖方法,即使用。然後,或者,在成功的情況下,在閉包中設置一個變量,然後添加一個。然後將該值推到下一個承諾。 – marneborn 2014-10-06 03:55:13

0

重構,並使用.then

angular.module("myModule") 
.controller("myController", ["$scope", "$http", function ($scope, $http) { 

    var controller = this; 

    angular.extend(controller, { 
     // ... 
     submit : submit, 
     handleSuccess : function() { /* ... success */ }, 
     handleError : function (err) { /* error */ } 
    }); 

    function submit (form) { 
     validateForm(form) 
      .then(controller.handleSuccess, controller.handleError) 
      .then(controller.cleanUp); 
    } 

    function validateForm (form) { 
     return $http.get("...").then(function (response) { return response.data; }); 
    } 

}]); 

它都應該是可讀的,現在。 此外,邏輯不會進入「成功」,而是進入隨後的.then調用中,因此您可以保持您的submit清潔和可讀。

但是你可以以往任何時候都這樣做

while (true) { 
} 

for (var i = 0; i < 10000000; i += 1) { } 

所有你正在做的是鎖定您的瀏覽器,阻止人們使用的頁面。
您無法對CSS進行動畫製作,您無法讀取AJAX值,您甚至無法關閉製表符(取決於瀏覽器)。

一切應該是被動的(基於事件)或異步的,使用回調或承諾。

相關問題