我是javascript的初学者,我试图找出为什么我的while循环实际上不会多次循环,即使条件总是满足。
我有一个发送API请求的函数:
var get_status = function(trid, count) {
console.log(count);
var req = {
method: 'GET',
url: 'theUrlHere',
headers: {'headers'}
}
$http(req).success(function(data) {
if (data.transaction_status != 'Pending') {
// do something with the data
console.log('true');
return true;
}
else {
console.log('False');
return false;
}
}).error(function(data) {
// show an error popup
console.log('true');
return true;
})
}
};
我想调用此函数直到它返回true,所以我这样称呼它:
var count = 0;
while (get_status(id, count) === false) {
count += 1;
}
只是添加了count变量以查看它循环的次数,即使“False'显示在控制台中。
我是否有一些误解的行为?
编辑我理解为什么这不会奏效。我的目的是只要事务状态处于挂起状态就显示iframe。我想到不断发送请求,直到交易状态是其他的“待定”,但我知道有更多的最佳方式。
答案 0 :(得分:1)
您试图在异步回调中返回,但不幸的是,这种回调无法正常工作。相反,您需要一个像async这样的模块,特别是whilst。
var count = 0;
var outcome = false;
async.whilst(
function () { outcome = false; },
function (callback) {
count++;
// Your code here, setting outcome instead of returning
var req = {
method: 'GET',
url: 'theUrlHere',
headers: {'headers'}
}
$http(req).success(function(data) {
if (data.transaction_status != 'Pending') {
outcome = true;
callback();
}
else {
outcome = false
callback();
}
}).error(function(data) {
outcome = true;
callback();
})
},
function (err) {
// All done!
}
);
但实际上,您正在寻找的行为可能是以预定义的时间间隔检查状态。在这种情况下,调整代码
var count = 0;
var outcome = false;
async.whilst(
function () { outcome = false; },
function (callback) {
count++;
// Your request stuff.
setTimeout(function () {
callback();
}, 1000); // Waits one second to begin next request
},
function (err) {
// All done!
}
);
答案 1 :(得分:1)
您的get_status()
函数未返回值。因此,它的返回值为undefined
,这是假的,因此您的while()
循环在第一次迭代后停止。
您在代码中使用的返回语句位于回调内,与get_status()
的返回值无关。
您尝试做的事情通常不是一个好的设计。看起来你想要一遍又一遍地运行一个给定的Ajax调用,直到你得到你想要的答案。这可能会破坏目标服务器。
如果您描述了您真正想要解决的问题,我们可以帮助您找到更好的方法来实现这一目标。最糟糕的情况是,您可以在请求之间延迟轮询服务器。
如果你想经常轮询,你可以这样做:
function get_status(trid, count) {
var req = {
method: 'GET',
url: 'theUrlHere',
headers: {'headers'}
}
return $http(req).then(function(data) {
return data.transaction_status;
});
}
function poll_status(callback) {
function next() {
get_status(...).then(function(status) {
if (status === "Pending") {
// poll once every two seconds
setTimeout(next, 2000);
} else {
// status is no longer pending, so call the callback and pass it the status
callback(status);
}
}, function(err) {
callback(err);
});
}
next();
}
poll_status(function(result) {
// done polling here, status no longer Pending
});
答案 2 :(得分:1)
这不是处理异步调用的正确方法,我创建了一个自动调用的递归函数。 (在这种情况下get_status
应该返回一个承诺)
<强>代码强>
var count = 0, id = 1;//id should be some value
(function myCall(promise){}
promise.then(function(data){
count += 1;
if(data)
myCall(get_status(id, count)); //call function on conditon
});
}(get_status(id, count))
方法(返回承诺)
var get_status = function(trid, count) {
console.log(count);
var req = {
method: 'GET',
url: 'theUrlHere',
headers: {'headers'}
}
//returning promise here
return $http(req).then(function(response) {
var data = response.data;
if (data.transaction_status != 'Pending') {
// do something with the data
console.log('true');
return true; //resolves the promise
}
else {
console.log('False');
return false; //resolves the promise
}
}, function(data) {
// show an error popup
console.log('true');
return true;
})
}
};