我有a
这样的标签:
<a class="pull-right" data-bind="click: $root.CheckTimeOut,
attr:{'href': webcontext + 'Reporting/CSVReport?id=' + id() +
'&session=' + $root.user.session() }">Table</a>
当用户点击此a
标签时,它会跳转到CheckTimeOut
功能以检查定时器是否已经结束:
self.CheckTimeOut = function(){
$.getJSON(package + "Backend?session="+ self.user.session(), function(result) {
if(result.result){
console.log('Timer is not over');
return true;
}else{
msg.error.timeOut();
return false;
}
})
}
我应该期待的是,如果后端返回result = true
则意味着计时器未结束,那么函数CheckTimeOut
应该返回true ,以便执行'href': webcontext + 'Reporting/CSVReport?id=' + id() + '&session=' + $root.user.session()
。否则,如果后端返回result = false
,则会出现消息错误,并且不会发生任何事情。但实际上,当后端返回result = true
时,CheckTimeOut
函数仅打印console.log ,但不返回true 。任何人都可以帮助我CheckTimeOut
函数为什么不返回值?
答案 0 :(得分:2)
您的CheckTimeOut
函数不返回任何内容:它调用异步方法,然后退出。您无法从处理结果的回调传递return true
或return false
,因为它会将值返回给JQuery,忽略结果。
您可以更改getJSON以进行同步调用,但这是不推荐,并且在JQuery中已弃用,因为它会导致阻塞调用。
有很多可能的方法,你可以在你的淘汰模型中保存URL,当执行.getJSON调用时,如果回调返回正确的true / false值,使用window.location = newURL;
答案 1 :(得分:1)
其他答案已经提到了你拥有的问题:CheckTimeout
函数立即返回(undefined
) ,{ {1}}调用异步稍后调用回调函数。这是设计的,你应该接受它。
这是使用计算的observable处理此问题的另一种方法,该observable根据Ajax调用的返回值触发视图模型更新:
getJSON
// Mock ajax calls:
var $ = {
getJSON: function(txt, callback) {
window.setTimeout(function() {
callback({ result: (Math.random() < 0.5) }); // Returns random result for testing
}, Math.random() * 1000 + 200); // Random latency between 200 and 1200 ms
}
};
function User(data) {
var self = this, _recentResponse = ko.observable(null);
self.uuid = ko.observable('fake-uuid-'+data);
self.id = ko.observable('fake-id-'+data);
self.recentResponse = ko.computed({
read: function() { return _recentResponse(); },
write: function(val) {
var resp = { txt: (new Date()).toISOString() + " " + val.toString(), val: val };
_recentResponse(resp);
self.responses.push(resp);
if (!!val) {
console.log('Timer is not over');
} else {
console.log("msg.error.timeOut()");
}
}
});
}
function ViewModel() {
var self = this;
self.users = ko.observableArray([new User('a1'), new User('a2')]);
self.CheckTimeOut = function(user) {
console.log(user);
$.getJSON("url-for-uuid" + user.uuid(), function(result) {
user.recentResponse(result.result);
})
return true;
}
};
var vm = new ViewModel();
ko.applyBindings(vm);
window.setInterval(function() { vm.CheckTimeOut(vm.users()[0]); } , 2500);
window.setInterval(function() { vm.CheckTimeOut(vm.users()[1]); } , 2500);
.msg { background: red; }
.success { background: green; }
答案 2 :(得分:0)
执行顺序为1-2-3-4-5
self.CheckTimeOut = function(){
// (1) Function begin executing
// Here we call $.getJSON function. The $.getJSON is asynchronous
$.getJSON(package + "Backend?session="+ self.user.session(),
// And pass new function as a parameter for $.getJSON function
function(result) {
// (4) After request has been completed
// this operations are performed
if(result.result){
console.log('Timer is not over');
// (5) And this is returned to the $.getJSON function
return true;
}else{
msg.error.timeOut();
// (5) And this is returned to the $.getJSON function also
return false;
}
})
// (2) $.getJSON sends request and immediately returns nothing and CheckTimeOut is continued
// Since there are no "return" statement in the CheckTimeOut function
// (3) it returns undefined, that you got as a result
}