我的问题非常简单,我认为很多程序员已经面临这个问题了。 我正在使用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对象并解析为成功或错误函数。如果是这种情况,那么此代码中的while循环不应该是无限的,但它是。通过调试,我发现如果我为变量'var'赋值,则只进行http调用,即循环结束时。 为什么http调用,作为延迟调用,等待while循环完成?
2)如果我删除了while循环,无论'var'的值是什么,函数都会返回。如果定义'var',我怎么能让它返回?
答案 0 :(得分:1)
JavaScript是单线程的,因此http成功/失败永远不会被执行,因为while循环正在进行。这导致你的无限循环。
返回承诺并在调用函数中使用它。
答案 1 :(得分: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响应。您应该练习只使用异步调用。
答案 2 :(得分: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值,你可能甚至无法关闭标签(取决于浏览器)。
使用回调或承诺,一切都应该是被动的(基于事件的)或异步的。