Javascript 添加了异步行为,无法使代码适合它
以前我用过Javascript 添加了异步行为,无法使代码适合它,javascript,jquery,ajax,Javascript,Jquery,Ajax,以前我用过 //get state MyClass.prototype.getState = function(key) { var value; switch(this._options.type){ case "cookie": value = $.cookie(key); break; case "localStorage":
//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");
};
已经使用了本地存储和cookie。现在我添加了在db中存储数据的功能,因此我必须使用ajax和异步函数。所以我改变了密码:
//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.end、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和prototype.getState
或从prototype.end、prototype.enden和prototype.setStep
?处理异步操作时,必须使用回调函数而不是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");
};
您无法从
end
返回(它可能总是返回undefined
,因为getState
将在回调之前返回)。你不能再使用像var x=obj.end()
这样的东西了,你必须重新考虑你的逻辑。对于setStep
,情况也是如此,您不能只返回getState
的返回值,因为它现在是异步的。doSomethingWithVal看起来像什么?可以是empy-like function(){}?可以,但在这种情况下,您甚至不需要回调。。。我的示例试图说明不能使用异步函数的返回值,必须在异步操作完成时向它们传递另一个要调用的函数。setTimeout
也只是一个模拟异步操作(如数据库访问)的示例。doSomethingWithVal或callback必须返回任何值吗?不,其目的就是不要使用return
语句。@AlanDert我添加了一些关于代码的特定注释,希望对您有所帮助。