我最近碰到了一个熟悉的javascript / jQuery计时错误,并且花了太长时间调试它。我需要的是一个更智能的调试路径来解决这个问题。
具体来说,我的问题是用户输入应该导致Mongo数据库调用,并且结果在经过一些数学运算后发送到显示的输出。但显示的输出很疯狂。但是,一旦我添加了FireBug断点,问题就消失了。那时我知道我有时间问题,但不知道如何解决它。
以下是错误之前的相关代码段:
handleDataCallBack : function(transport) {
var response = $.parseJSON(transport);
if(!hasErrors) { this.updatePage(response); }
},
accessDatabase : function(){
var params = { ... };
DAL.lookupDatabaseInfo(this.handleCallBackOutputPanel, this, params);
},
calculateValues: function() {
// some numerical values were updated on the page
}
onDomReady : function() {
// ...
//bind drop-down select change events
$('#someDropDown').change(function() {
me.accessDatabase();
me.calculateValues();
});
}
要解决这个问题,我所要做的就是从回调中的onDomReady
移动“calculateValues”方法:
handleDataCallBack : function(transport) {
var response = $.parseJSON(transport);
this.calculateValues();
if(!hasErrors) { this.updatePage(response); }
},
问题是数据库在计算开始之前没有响应。当然,回想起来很容易发现。但是我将来可以用什么方法来调试javascript / jQuery中的异步时序问题?这似乎在IDE工具的上下文之外。 FireBug没有帮助。是否有用于跟踪异步Web开发问题的工具?或者也许是一些经过时间考验的方法?
答案 0 :(得分:2)
我认为你的问题是由此造成的:
$('#someDropDown').change(function() {
me.accessDatabase();
me.calculateValues();
});
这个问题是您的计算是在通话结束后立即完成的。看到DB调用是异步的,calculate不会等待它。但是,你可以使用“回调”来做到这一点。我看到你确实尝试实现它,是的,这是正确的。但是,我觉得这更优雅:
calculateValues: function() {
// some numerical values were updated on the page
},
//since this is your general callback hander
//you hand over the return data AND the callbackAfter
handleDataCallBack: function(transport, callbackAfter) {
var response = $.parseJSON(transport);
//you may need to use apply, im lost in scoping here
callbackAfter();
//or
callbackAfter.apply(scope);
if (!hasErrors) {
this.updatePage(response);
}
},
accessDatabase: function(callbackAfter) {
var params = {};
//pass callbackAfter to the function,
//after this is done, pass it to the handler
DAL.lookupDatabaseInfo(this.handleCallBackOutputPanel, this, params, callbackAfter);
},
onDomReady: function() {
$('#someDropDown').change(function() {
me.accessDatabase(function() {
//send over what you want done after.
//we'll call it "callbackAfter" for easy tracing
me.calculateValues();
});
});
}