- 沙漏(特别是 Windows 上)。
- 旋转的皮球(通常在 Mac 机器上)。
- 应用程序基本上冻结了,然后过一段时间光标变化了。
这正是 Web 应用程序让人感到笨拙或缓慢的原因 —— 缺乏真正的交互性。按下按钮时,应用程序实际上变得不能使用,直到刚刚触发的请求得到响应。如果请求需要大量服务器处理,那么等待的时间可能很长(至少在这个多处理器、DSL 没有等待的世界中是如此)。
而异步请求不 等待服务器响应。发送请求后应用程序继续运行。用户仍然可以在 Web 表单中输入数据,甚至离开表单。没有旋转的皮球或者沙漏,应用程序也没有明显的冻结。服务器悄悄地响应请求,完成后告诉原来的请求者工作已经结束(具体的办法很快就会看到)。结果是,应用程序感觉不 那么迟钝或者缓慢,而是响应迅速、交互性强,感觉快多了。这仅仅是 Web 2.0 的一部分,但它是很重要的一部分。所有老套的 GUI 组件和 Web 设计范型都不能克服缓慢、同步的请求/响应模型。
Ajax 和 Web 2.0 最大的秘密是什么呢?秘密就在于 XMLHttpRequest
的一个简单属性 onreadystatechange
。
因为是异步请求,所以 JavaScript 方法不会等待服务器。因此代码将继续执行,就是说,将退出该方法而把控制返回给表单。用户可以继续输入信息,应用程序不会等待服务器。
这就提出了一个有趣的问题:服务器完成了请求之后会发生什么?如果什么也不发生显然不行,因此服务器在完成通过 XMLHttpRequest
发送给它的请求处理之后需要某种指示说明怎么做。
现在 onreadystatechange
属性该登场了。该属性允许指定一个回调函数。回调允许服务器反向调用 Web 页面中的代码。它也给了服务器一定程度的控制权,当服务器完成请求之后,会查看 XMLHttpRequest
对象,特别是 onreadystatechange
属性。然后调用该属性指定的任何方法。之所以称为回调是因为服务器向网页发起调用,无论网页本身在做什么。比方说,可能在用户坐在椅子上手没有碰键盘的时候调用该方法,但是也可能在用户输入、移动鼠标、滚动屏幕或者点击按钮时调用该方法。它并不关心用户在做什么。
这就是称之为异步的原因:用户在一层上操作表单,而在另一层上服务器响应请求并触发 onreadystatechange
属性指定的回调方法。