所以我在谷歌闭包中有一个客户端错误日志记录模块,它可以跟踪所有客户端错误。这些错误存储在队列中。这个想法是,一个新的错误弹出并存储在队列中,经过一段时间后,它被发送到服务器,队列被清空。但在我的代码中,回调函数并不能代表模型的正确实例。
goog.provide('model.ErrorLogger');
/**
* @constructor
*/
model.ErrorLogger = function() {
window.onerror = goog.bind(this.somefucntion() this);
};
goog.addSingletonGetter(model.ErrorLogger);
model.ErrorLogger.prototype.errors = [];
有一种方法负责存储错误
model.ErrorLogger.prototype.notify = function(err){
this.errors.push(err);
this.sendReport();
}
此方法将队列中的错误发送到服务器
model.ErrorLogger.prototype.sendReport = function(){
dataModel.xhrPost(rid,url,JSON.stringify(this.errors),function(responseData){
this.errors = []; //This error queue should have contents but is showing undefined
});
}
因此,当响应返回回调函数时,错误队列在调试时显示为未定义,而不是显示内容。因此,基本上,这个值应该没有被正确存储/传递。基本上,在错误队列将错误发送到服务器后,我无法清空它。下次出现新错误时,队列中仍然存在旧错误。
这很正常,因为回调函数中使用的"This"不是指向主对象,而是指向回调函数您必须像这个一样绑定回调函数
model.ErrorLogger.prototype.sendReport = function(){
dataModel.xhrPost(rid,url,JSON.stringify(this.errors),(function(responseData){
this.errors = []; //This error queue should have contents but is showing undefined
}).bind(this));
}
或者订阅xhr对象触发的完整事件,并使用这种方法(更干净(
goog.require('goog.net.XhrIo');
var xhr = new goog.net.XhrIo();
goog.events.listen(xhr, goog.net.EventType.COMPLETE, function(e) {
obj = this.getResponseJson();
// get your response here
}, **false, this**);
xhr.send(url);
此处提供更多信息https://developers.google.com/closure/library/docs/xhrio
这就是我解决问题的方法
model.ErrorLogger.prototype.sendReport = function(){
dataModel.xhrPost(rid,url,JSON.stringify(this.errors),goog.bind(function(responseData){
this.errors = []; //This error queue should have contents but is showing undefined
},this));
}
解释:goog.bind等效于function.prototype.bind,但第一个参数是要绑定到的函数,第二个参数是应该绑定的"this"值,所有剩余的参数都绑定到函数的形式参数。
JavaScript有第一类函数,但它们不是与"this"值继承绑定的,所以除非您绑定它,否则该值取决于它的调用方式:
var x = { f : handler };
x.f(); // handler is called with "x" as the this value.
handler(); // unspecified this
传统上,如果"this"值未指定、未定义或为null,则它通常被强制到全局this"window"中。但是,如果在EcmaScript 5严格模式下运行,则该值保持不变(未指定为"未定义"(。