我知道javascript不使用Class
,至少不是常识。我想知道如何在类变量中返回并保存AJAX返回值,而不是在回调中调用多个方法。
var Reader = function(){
//Initialize some variables
this.data = null;
}
Reader.prototype.makeAjaxCall = function(urlPath){
//Make and Ajax call and return some value
Ajax.success(function(data){
this.data = data;
});
}
Reader.prototype.searchData = function(param){
//Needs access to this.data
}
Reader.prototype.findData = function(id){
//Needs access to this.data
}
Reader.prototype.deleteItem = function(id){
// Needs access to this.data
}
在上面的代码中,需要在data
内调用需要访问ajax success callback
属性的任何函数,所以如果我有十个方法需要数据,我将不得不排除所有他们在回调中,我感觉不对。如何最小化回调中的函数数量,并以其他方式确保函数成功并将数据保存为实例变量data
。
答案 0 :(得分:7)
最重要的部分是如何使用JavaScript处理异步数据。有一些经过良好测试的解决方案:功能和承诺。
在两个cass中,Reader应该有一个构造函数,它可以像这样分配数据:
function Reader(data) {
this.data = data;
}
回调方法需要一个具有回调函数的工厂函数。
function getReader(url, callBack) {
Ajax.success(function(data){
callBack( new Reader(data) );
});
}
并像
一样使用它getReader(url, function(reader) {
reader.searchData();
});
Promise -approach不需要立即回调,因此结果可以存储在变量中并作为变量传递,具有一些优势:
function getReaderPromise(url) {
return new Promise( function( resolve, reject ) {
Ajax.success(function(data){
resolve( new Reader(data) );
});
});
}
但是,使用promise通常需要调用promise的 then 函数:
getReaderPromise(url).then( function(reader) {
reader.searchData();
});
// Fat arrow syntax
getReaderPromise(url).then( (reader) => {
reader.searchData();
});
将来你可以使用带有像
这样的产量的ES6生成器去掉Promises的回调let reader = yield getReaderPromise( url );
答案 1 :(得分:4)
您可以尝试以下方式:
var Reader = function(){
//Initialize some variables
this.data = null;
}
Reader.prototype.makeAjaxCall = function(urlPath){
//Make and Ajax call and return some value
this.data = Ajax({url: urlPath}); // return promise
}
Reader.prototype.searchData = function(param){
//Needs access to this.data
if(this.data){
this.data.then(...);
}
}
Reader.prototype.findData = function(id){
//Needs access to this.data
if(this.data){
this.data.then(...);
}
}
Reader.prototype.deleteItem = function(id){
// Needs access to this.data
if(this.data){
this.data.then(...);
}
}
答案 2 :(得分:2)
在您的代码中:
Reader.prototype.makeAjaxCall = function(urlPath){
//Make and Ajax call and return some value
Ajax.success(function(data){
this.data = data;
});
}
"这"不是Reader实例上下文,您应该将其更改为
Reader.prototype.makeAjaxCall = function(urlPath){
var myThis = this;
//Make and Ajax call and return some value
Ajax.success(function(data){
myThis .data = data;
});
}
在myThis变量中保持指向Reader实例的指针并访问成功函数
答案 3 :(得分:1)
这是我认为解决它的好方法,它需要几个回调但是
var Reader = function(){
//Initialize some variables
this.data = null;
}
Reader.prototype.makeAjaxCall = function(urlPath, cb) {
//Make and Ajax call and return some value
Ajax.success(function(data) {
this.data = data;
if(cb) cb();
});
}
Reader.prototype.searchData = function(param){
var self = this;
if(!this.data) {
// data doesn't exist, make request
this.makeAjaxCall(urlPath, function() {
// when is ready, retry
self.searchData(param);
});
return;
}
// do whatever you need...
// data exists
}
Reader.prototype.findData = function(id){
var self = this;
if(!this.data) {
// data doesn't exist, make request
this.makeAjaxCall(urlPath, function() {
// when is ready, retry
self.findData(id);
});
return;
}
// do whatever you need...
// data exists
}
Reader.prototype.deleteItem = function(id){
var self = this;
if(!this.data) {
// data doesn't exist, make request
this.makeAjaxCall(urlPath, function() {
// when is ready, retry
self.deleteItem(id);
});
return;
}
// do whatever you need...
// data exists
}
答案 4 :(得分:1)
你的问题是关于'this'键的混淆。
在函数中使用它时,它使用该函数的上下文。
所以这稍微使用了不同的上下文:
Reader.prototype.makeAjaxCall = function(urlPath){
//Make and Ajax call and return some value
Ajax.success(function(data){
this.data = data;
});
}
比这个:
Reader.prototype.makeAjaxCall = function(urlPath){
var readerContext = this;
//Make and Ajax call and return some value
Ajax.success(function(data){
readerContext.data = data;
});
}
这是解决问题的方法。
答案 5 :(得分:0)
您可以执行类似
的操作 Reader.prototype.searchData = function(param){
var self = this;
if (!this.data) {
setTimeout(function() { self.searchData(param) }, 1000);
return;
}
...
}
答案 6 :(得分:0)
尝试改变这一点:
Reader.prototype.makeAjaxCall = function(urlPath){
//Make and Ajax call and return some value
Ajax.success(function(data){
this.data = data;
});
}
到此:
Reader.prototype.makeAjaxCall = function(urlPath){
var _this = this;
//Make and Ajax call and return some value
Ajax.success(function(data){
_this.data = data;
});
}
答案 7 :(得分:0)
一个简单的解决方案是将所有函数调用放在另一个函数中,并仅从回调函数中调用该函数:
var Reader = function(){
//Initialize some variables
this.data = null;
}
Reader.prototype.makeAjaxCall = function(urlPath){
//Make and Ajax call and return some value
var that = this;
Ajax.success(function(data){
that.data = data;
that.makeOtherCalls();
});
};
Reader.prototype.makeOtherCalls = function(){
// call the functions that need this.data here
};
答案 8 :(得分:0)
您可以使用context
this
设置在$.ajax()
回调$.ajax()
处设置Reader
;包括// set `this` at `$.ajax()` to context of `Reader` instance
var Reader = function(context) {
//Initialize some variables
this.data = null;
// handle `$.ajax()` errors
this.err = function(jqxhr, textStatus, errorThrown) {
console.log(textStatus, errorThrown, this);
}
this.makeAjaxCall = function(urlPath) {
//Make and Ajax call and return some value
return $.ajax({
url: urlPath,
// set `context` to `this`
context: context || this,
})
.then(function(data) {
this.data = data;
console.log("in `Reader.makeAjaxCall`, this is:", this);
}, this.err);
}
this.searchData = function(param) {
//Needs access to this.data
console.log("in `Reader.searchData`", this.data);
}
this.findData = function(id) {
//Needs access to this.data
console.log("in `Reader.findData`", this.data);
}
this.deleteItem = function(id) {
// Needs access to this.data
console.log("in `Reader.deleteItem`", this.data);
}
}
var reader = new Reader();
reader.makeAjaxCall("")
.then(reader.searchData)
.then(reader.findData)
.then(reader.deleteItem)
.then(function() {
console.log("complete", this.data, this)
})
实例中的错误处理函数。
jpa:
properties:
jadira.usertype.autoRegisterUserTypes: true
答案 9 :(得分:0)
人们痴迷于使用原型来在类中创建函数,但是通过使用带有'this'引用的函数,有一种更简洁的方法。然后,您可以通过自变量访问类的内部工作。
例如:
var Reader = function(){
var self = this;
//Initialize some variables
this.data = null;
this.makeAjaxCall = function(urlPath){
Ajax.success(function(data){
self.data = data;
});
}
}
然后在原型方法中,您可以使用以下数据:
this.data
您可以使用以下方法调用ajax方法:
this.makeAjaxCall(url);
您可以使用以下方法从类外部调用ajax方法:
var myReader = new Reader();
myReader.makeAjaxCall(url);
按照正常情况。
答案 10 :(得分:0)
您可以简单地使用全局JS变量来满足此类要求。请检查以下代码
var globalData; /* This is global.It can be accessed anywhere */
var Reader = function(){
//Initialize some variables
globalData = null;
}
Reader.prototype.makeAjaxCall = function(urlPath){
//Make and Ajax call and return some value
Ajax.success(function(data){
globalData = data;
});
}
Reader.prototype.searchData = function(param){
//Access globalData here
}
Reader.prototype.findData = function(id){
//Access globalData here
}
Reader.prototype.deleteItem = function(id){
//Access globalData here
}
答案 11 :(得分:0)
为了将返回数据保存在所谓的Class
变量中,根据您的示例,您需要了解使用this
关键字的上下文。
在你的例子中
Reader.prototype.makeAjaxCall = function(urlPath){
//Make and Ajax call and return some value
Ajax.success(function(data){
this.data = data;
});
}
this
被称为Ajax对象。
由于Reader对象中的this.data
几乎封装在Reader对象的上下文中,因此您需要在进行Ajax
调用之前将其保存在本地,以便能够通过呼叫。
像这样:
Reader.prototype.makeAjaxCall = function(urlPath){
var _this = this;
//Make and Ajax call and return some value
Ajax.success(function(data){
_this.data = data;
});
}
这几乎解决了上下文问题,在进行函数调用时非常有用。 一个简单的解决方案是只定义一个局部变量,您可以在其中临时存储数据,然后使用它来覆盖this.data的值。 代码应如下所示:
Reader.prototype.makeAjaxCall = function(urlPath){
var tempData;
//Make and Ajax call and return some value
Ajax.success(function(data){
tempData = data;
});
this.data = tempData;
}
答案 12 :(得分:0)
我为此开发了自己的jQuery ajax包装器,但它确实需要jQuery ...如果这有助于检查我的github repo
JQPS Framework v. 1.1b - Github
这可以帮到你很多,它使用命名空间的OOP(你正在寻找的类),比如Myobject.vars.anything = value(来自回调)
电话示例
Main.ajaxCall('auth','login','POST','TEXT',{dataObj},{Utils:{1:'setVar|Main,myVar,,callback',2:'anyOtherFunction'}},false);
这将触发对http://yoursite.com/auth/login的ajax调用,dataObj
作为post对象,在回调时将调用第一个函数,在我们的例子中Utils.setVar()
这将存储响应从Main.vars.myVar
中的回调中我们在回调对象中定义它,之后第二个函数将按照调用Utils.anyOtherFunction()
中的定义被触发和执行...你可以添加你想要的函数数量在回调中。
有关更多信息,您可以检查来自github的自述文件,这是为同步和异步调用设置的,但它确实需要jQuery,没有它就无法工作。