2014-10-05 41 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值,您甚至无法关闭制表符(取决于浏览器)。

一切应该是被动的(基于事件)或异步的,使用回调或承诺。

相关问题