【发布时间】:2013-02-12 15:47:22
【问题描述】:
我正在尝试为在 JS/jQuery 中实现的应用程序提供状态值字典。这些值必须从服务器(ajax)中获取。我想以异步方式执行此操作,以便可以在初始化期间启动该请求。对值的实际访问应该稍后同步完成,以使代码易于理解。 目前(非常)简化的代码如下所示:
初始化:
$(document).ready(function(){
Status.fetch();
})
结构:
Status:{
Valid:new $.Deferred(),
Server:{},
/* ... */
fetch:function(){
if (Status.Valid.isResolved()){
// status already present due to a past request
return Status.Valid.promise();
}else{
// fetch status information from server
$.ajax({
type: 'GET',
url: 'status.php'),
cache: true,
dataType: 'json'
}).done(function(response){
$.each(response,function(key,val){
Status.Server[key]=val;
});
Status.Valid.resolve(Status.Server);
}).fail(function(response){
Status.Valid.reject(NaN);
});
return Status.Valid.promise();
}
}, // Status.fetch
getServerAspect:function(aspect){
$.when(
Status.fetch()
).done(function(server){
return server[aspect];
}).fail(function(server){
return NaN;
})
/* whyever: processing always comes here, which I don't understand... */
}, // Status.getServerAspect
} // Status
Status.Server 被 ajax 调用填充(有效)。 Status.getServerAspect() 是一个允许同步访问存储在Status.Server 结构中的方面的方法示例(不 工作)。
基本思想是结构的异步填充在结构被访问之前运行。每个(同步)访问都意味着要么立即返回所引用的方面,要么阻塞直到该值出现。但是无论我在Status.getServerAspect() 中尝试什么风格,该方法都会立即返回,而没有我可以在调用范围内使用的任何方面值。
我显然在理解使用延迟对象的基本概念方面存在问题。我一直使用它们进行同步处理,就像魅力一样。但这意味着您必须在整个应用程序中使用异步样式。对于这个特殊功能,我更喜欢同步风格,以便条件表达式保持简单:
if ('somevalue'==Status.getServerAspect('someaspect'))
...do something...
在异步和同步处理之间建立“桥梁”的诀窍是什么?
【问题讨论】:
-
你用什么来“阻止”直到你有数据?据我所知,除了使 ajax 同步之外,这在现代浏览器中是不可能的
-
@KevinB 我尝试使用由异步获取过程解决的延迟对象。后来我尝试通过在
$.when中评估它来使用该延迟对象来阻止访问。至少是这样的想法...... -
对,但这不是阻塞,它是异步的。您无法从
.done()回调中返回数据。 -
您需要设置 async 参数并将其设置为 false 以允许 ajax 在继续执行其余代码之前完成其请求
-
要么让你的 ajax 同步,要么让你的代码异步。你不能两者兼得。
标签: javascript jquery asynchronous