这个问题肯定可以应用于jQuery,但在这种情况下,我指的是Prototype。在原型文档中,它说,
因为同步使用是相当的 令人不安,通常味道不好,你 应该避免改变这一点。严重。
我不确定使用同步ajax调用有什么缺点。似乎有许多实例必须等待调用返回(不使用特定的回调函数)。例如,我目前使用Prototype的onSuccess, onFailure and onComplete
来处理其余的代码。
但是,我使用的Web服务(所有内部)跨越大多数项目,我的任务是创建更多可重用的代码。一个示例是返回客户属性的客户类。一个简单的例子(请记住,我只显示基本功能以保持简单):
Customer = Class.create({
initialize: function(customerId) {
new Ajax.Request('some-url', {
method: 'get',
parameters: {
customerId: customerId
},
onSuccess: this.setCustomerInfo.bind(this)
}
},
setCustomerInfo: function(response) {
//for the sake of this example I will leave out the JSON validation
this.customerInfo = response.responseText.evalJSON();
}
});
因此,使用这个简单的类我可以在任何项目中执行以下操作来获取客户信息。
var customer = new Customer(1);
//now I have the customer info
document.write(customer.customerInfo.firstName);
使用上述代码不会打印出客户的名字。这是因为ajax调用是异步的。无论Web服务是否带回客户数据,它都将执行document.write
。但是,在数据恢复并设置了客户变量之前,我不想做任何事情。为了解决这个问题,我将ajax调用设置为synchronous,这样浏览器就不会继续,直到new Customer(1);
完成。
这种方法似乎有效(将异步设置为false)但是阅读Prototype文档会让我停下来。使用这种方法有什么缺点?有没有其他方法可以做到,效率更高等等?
我将不胜感激。
答案 0 :(得分:10)
让我们提醒您,JavaScript是单线程
同步IO呼叫阻止整个线程
一个简单的解决方法是使用回调来使用异步样式编程。
Customer = Class.create({
initialize: function(customerId, cb) {
new Ajax.Request('some-url', {
method: 'get',
parameters: {
customerId: customerId
},
onSuccess: (function() {
this.setCustomerInfo.apply(this, arguments);
cb.apply(this, arguments);
}).bind(this)
}
},
setCustomerInfo: function(response) {
//for the sake of this example I will leave out the JSON validation
this.customerInfo = response.responseText.evalJSON();
}
});
var c = new Customer(1, function() {
document.write(customer.customerInfo.firstName);
});
答案 1 :(得分:6)
嗯,除了非常而非JavaScript之外,它还具有 完全阻止浏览器用户界面 这样的令人愉快的效果。这不是一个小问题。
做了一些研究,找到了很酷的东西。原型基于XMLHttpRequest.open的“异步”。根据{{3}},这不是规范的必要部分,它将阻止“onreadystatechange”。答案 2 :(得分:2)
大多数人对同步ajax调用不满意,因为它会在完成之前冻结UI,因为它不会允许代码继续完成,直到它完成。我想你可以说,在界面中造成口吃。
答案 3 :(得分:2)
好吧,如果用户在同步调用完成时生成加载图像,我发现阻止UI是一个问题。它可以与提交表单相同。