运行回调时,无法访问JS类中的函数



我正在开发TVML/TVJS应用程序,在使用Javascript中的类时遇到了问题。

我的启动应用程序.js文件调用一个函数

resourceLoader = new ResourceLoader();
resourceLoader.getHomeScreen();

我有一个名为ResourceLoader.js的单独文件,其中包含以下内容:

class ResourceLoader {
getHomeScreen() {
var homeData = BASEURL + "/home.json";
var homeTemplate = BASEURL + "/home.tvml";
this.getRemoteJSON(homeData, homeTemplate, this._jsonLoaded);
}
_jsonLoaded(template, jsonString) {
var parsedJSON = JSON.parse(jsonString);
this.getRemoteXMLFile(template, parsedJSON);
}
getRemoteJSON(file, template, callback) {
var xhr = new XMLHttpRequest();
xhr.responseType = "text";
xhr.addEventListener("load", function() {
callback(template, xhr.responseText);
}, false);
xhr.open("GET", file, true);
xhr.send();
}
getRemoteXMLFile(template, json) {
var xhr = new XMLHttpRequest();
xhr.responseType = "xml";
xhr.addEventListener("load", function() {
loadRemoteFile(xhr.responseText, json);
}, false);
xhr.open("GET", template, true);
xhr.send();
}
}

(BASEURL是application.js中定义的全局变量)

一开始一切都很好。调用getHomeScreen()时,它设法调用getRemoteJSON()并将_jsonLoaded()作为回调传递。getRemoteJSON执行AJAX调用,然后运行回调。这就是问题发生的地方。一旦进入_jsonLoaded,"this"就会变成未定义的,所以当我调用this.getRemoteXMLFile时,我会得到错误消息"undefined不是对象(正在评估"this.getRemoteXMLFile")">

为什么"this"在getHomeScreen()中有效,而在_jsonLoaded()中无效?如何从_jsonLoaded()访问getRemoteXMLFile函数?

谢谢你的帮助。

这是因为回调不是一个函数。

一个好的解决方案是使用ES6 Promises。

下面是一个使用AJAX和Promise 获取数据的示例

getJson(url) {
return new Promise(
(resolve, reject) => {
this.get(url).then(
(value) => {
resolve(JSON.parse(value));
},
function (reason) {
console.error(reason);
reject(new Error(reason));
}
)
}
)
}

以及如何将其称为

getJson('http://jsonplaceholder.typicode.com/posts/1').then(
(value) => {
console.log(value);
},
function (reason) {
console.error(reason);
}
);

为什么"this"在getHomeScreen()中有效,而在_jsonLoaded()中无效?如何从_jsonLoaded()访问getRemoteXMLFile函数?

从技术上讲,它不是TVML应用程序特有的,而是一个通用的JS问题,所以让我根据JavaScript回答this(并非双关语)。

当您调用getHomeScreen时,您会在对象实例resourceLoader.getHomeScreen()上调用它,因此会保留this上下文。但是,当您将_jsonLoaded函数作为函数的回调参数传递并执行callback(template, xhr.responseText)时,对象上下文将丢失。

最近引入的JavaScriptclass关键字可能会让具有纯OOP语言背景的人感到困惑,因为它不是面向对象的继承,而只是JavaScript中古老原型继承的语法糖。因此,如果一个人碰巧属于同一个群体,最好了解其中的差异和陷阱。

话虽如此,对于您的直接问题语句,一个直接而简单的解决方案是,每当您将函数作为回调传递时,都要bindthis上下文。

this.getRemoteJSON(homeData, homeTemplate, this._jsonLoaded.bind(this));

旁注:您是否尝试过构建TVML应用程序的atvjs框架?它可以让你在没有太多噪音的情况下构建并快速原型化应用程序,抽象出传统TVML应用程序的潜在麻烦和复杂性

相关内容

  • 没有找到相关文章

最新更新