从上面的代码中我们可以发现这三个步骤都是基于当前异步刷新的Request对象进行的。当一个新的异步刷新被发起时,之前的那个异步刷新将被取消。与此同时,旧的Request对象将从PRM对象中除去,并使用新的对象来替换它(step 1)。在得到了端的Response之后,我们会检验Response的Request对象是否为PRM对象上的那个。如果两个Request对象并不是同一个,则表示获得的Response对象并不是当前的Request对象所对应的那个,我们则会将其直接丢弃(step 2)。在异步刷新结束之后,PRM对象上的Request对象则会被去除(step 3)。
下面的示意图向您展示了用户连续发出两个异步请求时的状况。
这是用户在前一个异步刷新等待端回应时发起第二个异步刷新的情况。那么如果一个信息的异步刷新请求在前一个正在加载脚本文件时被发起了,又会出现什么状况呢?我们可以通过下一幅示意图来观察这个状况:
第二个请求在第一次异步刷新加载脚本时发起。如果在第二次请求得到服务器端的结果之前脚本文件加载完成,则PRM对象上的Request对象就被去除了——即时目前的对象并不属于第一次异步刷新。这时,当第二次异步刷新得到服务器端的回应之后,PRM就会立即将它丢弃,因为Request对象已经不存在了。
如何避免
新的异步刷新被取消了,是吗?并非如此。如果一个异步请求被取消的话,endRequest事件将会被触发,但是新的异步刷新在我们无法控制的情况下被中断了。由于客户端生命周期中的事件无法被触发,开发人员设计的一些逻辑也有可能会被中断。我们究竟该如何防止这样的情况出现呢?幸运的是,我们很容易做到这一点:
优化脚本加载时间。
避免一个已经发起的异步刷新被取消了。
避免在PRM的“_processingRequest”变量为true的时候取消一个异步刷新。
其中的最后一点可能还需要再多解释一下。PRM对象上的“_processingRequest”变量会在收到服务器端回应时被设为true,并且在整个异步刷新过程结束时设为false。如果您的代码发现这个值为true的话就必须当心了,由于此时PRM正在异步地加载脚本文件。这正是产生问题的主要原因。