这是一个javascript函数:
function getValue(key) {
var value;
switch(_options.myType){
case "cookie":
value = readFromCookie(key);
break;
case "localStorage":
value = readFromLocalStorage(key);
break;
case "db":
//return value from the server
// how do I wait for the result?
$.ajax({
type: "GET",
url: "123",
data: { .... },
success: function(data){
value = data;
}
});
break;
}
return value;
};
如果发送ajax请求,我需要等待直到ajax请求完成。我该怎么办?
并非我不能在没有计算值的情况下离开该函数。这意味着我不能在success:
处理程序中放置一个函数,它稍后会返回值(或者我可能不明白?)。所以它必须在函数getValue()
中计算。
更新
P.S。那么如何重构我的代码才能在success:
处理程序中使用回调?以下是代码的第二部分:
MyClass123.prototype.myMethod = function(value) {
//..............
var var1 = this.getValue("key1");
if (var1 == "123") { ... }
else { .... }
//..............
}
};
答案 0 :(得分:8)
请参阅下面的后续行动
你可以使ajax请求同步,但这通常是一个坏主意(并且jQuery不会再支持它了。)
相反,让getValue
接受回调:
function getValue(key, callback) {
switch(_options.myType){
case "cookie":
setTimeout(function() {
callback(readFromCookie(key));
}, 0);
break;
case "localStorage":
setTimeout(function() {
callback(readFromLocalStorage(key));
}, 0);
break;
case "db":
//return value from the server
// how do I wait for the result?
$.ajax({
type: "GET",
url: "123",
data: { .... },
success: function(data){
callback(data);
}
});
break;
}
}
请注意,我正在setTimeout
和readFromCookie
回调使用readFromLocalStorage
。为什么?因为如果getValue
可能异步返回其值,那么总是这样做。使用超时0
要求浏览器尽快将控制权返回给浏览器(尽管它通常被限制在不低于5-10毫秒)。
重新评论以下内容:
你读过我写的东西吗?我说我出于某种原因不能这样做。
我错过了这一点,但在充分尊重的情况下,你可以。它可能需要对代码进行一些重构,但是可以执行它,并且应该。这就是现代Web应用程序的工作方式。如果您的结构不支持它,则需要修复结构。您可以在请求中使用async: false
作为临时解决方法,直到您可以正确执行。 (嘿,我们都去过那里,不得不做那样的事情。)请注意,它计划在很长时间内退役(只需jQuery支持它,你仍然可以直接使用XHR来做同步请求)。
更新您的更新问题,以下是更新该代码的方法:
MyClass123.prototype.myMethod = function(value) {
this.getState("key1", function(var1) {
// ^--- Note the var becomes an arg
if var1 == "123"{ ... }
else { .... }
});
};
请注意它实际变化的程度。用于跟随调用getState
的逻辑将转入您传入其中的回调。
答案 1 :(得分:2)
您可以通过指定async: false
- 来使AJAX请求同步,这是不推荐但可能的。 如果绝对是您的{{1}在AJAX请求返回之前,函数不应该返回,然后getValue()
就可以了。
async
使用$.ajax({
type: "GET",
url: "123",
async: false // NEW
data: { .... },
success: function(data){
value = data;
}
});
和then
的替代方案:
when
并且您在其中调用它,请将其命名为:
function getValue(key, callback) {
switch(_options.myType){
...
case "db":
return $.ajax({ // note the 'return'
type: "GET",
url: "123",
...
});
}
}
答案 2 :(得分:2)
正确的做法是重构您的程序流,以便您可以将您的逻辑放在success
处理程序中。
您可以使用async
选项使Ajax请求同步,但这很愚蠢。它会降低你的应用程序的速度,因为浏览器窗口会冻结,直到请求成功(或超时)。它并不经常用于JavaScript开发,而且有充分的理由。