在我以前使用
之前//get state
MyClass.prototype.getState = function(key) {
var value;
switch(this._options.type){
case "cookie":
value = $.cookie(key);
break;
case "localStorage":
value = window.localStorage.getItem(key);
break;
}
this._options.afterGetState(key, value);
return value;
};
//set state
MyClass.prototype.setState = function(key, value) {
switch(this._options.type){
case "cookie":
$.cookie(key, value);
break;
case "localStorage":
window.localStorage.setItem(key, value));
break;
}
return this._options.afterSetState(key, value);
};
MyClass.prototype.ended = function() {
return !!this.getState("is_ended");
};
MyClass.prototype.setStep = function(value) {
if (value != null) {
this._current = value;
return this.setState("step", value);
} else {
this._current = this.getState("step");
if (this._current === null || this._current === "null") {
return this._current = 0;
} else {
return this._current = parseInt(this._current);
}
}
};
MyClass.prototype.end = function() {
this.setState("end", "true");
};
已经使用了localStorage和cookie。现在我添加了在db中存储数据的功能,因此我必须使用ajax和async函数。所以我改变了代码:
//get state async
MyClass.prototype.getState = function(key, callback) {
oldThis = this;
//h-mmm... what if callback is null or undefined? Will it work for function(){ }?
callback = typeof callback != 'undefined' ? callback : function(){ }
switch(this._options.storageType){
case "cookie":
setTimeout(function(){
value = callback($.cookie(key));
oldThis._options.afterGetState(key, value);
return value;
},
0);
break;
case "localStorage":
setTimeout(function(){
callback(window.localStorage.getItem(key));
oldThis._options.afterGetState(key, value);
return value;
},
0);
break;
case "db":
$.ajax({
type: "GET",
url: "/123",
data: { .... },
success: function(data){
value = callback(data);
oldThis._options.afterGetState(key, value);
return value;
},
error: function() {
alert('Error occured');
return undefined;
}
});
break;
}
};
//set state async
MyClass.prototype.setState = function(key, value, callback) {
oldThis = this;
callback = callback || function(){ }
switch(this._options.storageType){
case "cookie":
setTimeout(function(){
callback($.cookie(key, value));
return oldThis._options.afterSetState(key, value);
},
0);
break;
case "localStorage":
setTimeout(function(){
callback(window.localStorage.setItem(key, value));
return oldThis._options.afterSetState(key, value);
},
0);
break;
case "database":
$.ajax({
type: "POST",
url: "123",
data: { .... },
success: function(data){
callback(data);
return oldThis._options.afterSetState(key, value);
},
error: function() {
alert('Error occured');
}
});
break;
}
};
那么如何更改prototype.ended,prototype.setStep和prototype.end函数呢?这是我做的:
//nothing has been changed. Is this correct? It seems to be so.
MyClass.prototype.ended = function() {
return !!this.getState("end");
};
MyClass.prototype.setStep = function(value) {
if (value != null) {
this._current = value;
return this.setState("step", value, function(value){ return value; });
} else {
oldThis = this;
this.getState("step", function(value){ oldThis._current = value; });
if (this._current === null || this._current === "null") {
return this._current = 0;
} else {
return this._current = parseInt(this._current);
}
}
};
//nothing has been changed. Is this correct as well?
MyClass.prototype.end = function() {
this.setState("end", "true");
};
最重要的是,我无法确定应该从以下位置返回值:来自prototype.setState and prototype.getState
还是来自prototype.end, prototype.enden and prototype.setStep
?
答案 0 :(得分:1)
在处理异步操作时,必须使用回调函数而不是return
语句。
例如,这个同步代码:
function syncFunc() {
return 10;
}
var val = syncFunc();
doSomethingWithVal(val);
当函数是异步时,应该变成这样的东西:
function asyncFunc(callback) {
setTimeout(function() {
var data = 10;
// Call the callback when async op is finished
callback(data);
}, 1000);
}
asyncFunc(doSomethingWithVal);
就您的特定代码而言,这意味着这不起作用:
MyClass.prototype.ended = function() {
return !!this.getState("end");
};
您无法从ended
返回(它可能始终返回undefined
,因为getState
将在回调之前返回)。你不能再使用像var x = obj.ended()
这样的东西了,你必须重新考虑你的逻辑。对于setStep
也是如此,你不能只返回getState
的返回值,因为它现在是异步的。