是否可以使函数在满足条件之前不返回

Is it possible to make a function not return until a condition is met?

本文关键字:返回 条件 满足 可以使 函数 是否      更新时间:2023-09-26

我的问题很简单,我想很多程序员一定已经面临过这个问题。我使用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调用时,它返回一个promise对象,并解析为success或error函数。如果是这样的话,那么这段代码中的while循环不应该是无限的,但它确实是无限的。通过调试,我发现如果我给变量"var"赋值,那么只会进行http调用,即循环结束时。http调用作为一个延迟调用,为什么要等待while循环完成?

2) 如果我删除while循环,无论"var"的值是多少,函数都会返回。只有在定义了"var"的情况下,我才能使它返回?

JavaScript是单线程的,所以http成功/失败永远不会被执行,因为while循环正在进行。这导致了你的无限循环。

返回promise并在调用函数中使用它。

这样的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响应的时间内减慢执行速度。您应该练习只使用异步调用。

Refactor,并使用.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值,你可能甚至不能关闭选项卡(取决于浏览器)。

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