服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > 专题栏目 > WEB2.0新技术 > 查看文档

五种ajax反模式 避免代码陷阱

  通过理解错误的编码方式,可以更好地了解如何正确地进行编码。当然,编写 asynchronous javascript + xml(ajax)有正确的方法,也有错误的方法。本文将讨论一些需要避免的常见编码实践……

  如果人们在第一次就能够将所有事情全部做对,那么这个世界将变得完全不同。ajax 也是如此。我做了大量的工作以支持 ajax 开发人员(包括我自己),包括编码、撰写文章和演讲。通过这些工作,我学到了很多关于正确和错误编写 ajax 的知识。在这篇文章中,我将介绍 ajax 代码中常见的五种反模式。

  您可能会问,什么是反模式(anti-pattern)?反模式 就是频繁出现的应用程序设计缺陷,已经成为所有人都应该注意的问题。我在这里将从较高的层次进行讨论,而不涉及语法错误和链接问题。

  大多数开发人员听说过关于反模式的一个很好的例子:结构化查询语言(structured query language,sql)的错误使用导致 web 站点受到 sql 注入攻击。这种反模式使得公司损失惨重,并暴露了客户记录,而且不幸的是没有一种编程语言可以幸免。因此,我们有必要了解这种模式发生的原理和原因,以及如何避免。

  ajax 反模式也是如此。我并不是说它们将造成公司损失数十亿的收入,但是它们可以搞垮服务器或者提供糟糕的用户体验,这种代价不仅昂贵,而且令人沮丧。

  如果理解了发生错误的内容,您将学到很多知识。很多时候,人们仅仅把 ajax 看作是一种在加载页面后从服务器取回 xml 的方式。这种观点非常狭隘,并且如果被错误使用,将引发应用程序的性能问题。在本文中,我将解释这种观点之所以错误的原因,以及如何修复这种错误。

  在没有必要的时候轮询计时器

  我见到的很多 ajax 问题都和滥用 javascript 语言内置的计时器功能有关。其中的关键方法是 window.setinterval()。只要看到这种方法,就需要稍微提高警惕;为什么要使用一个计时器呢?当然,计时器有其用途 ―― 比如,动画。

  window.setinterval() 方法告诉页面以特定的时间间隔回调某个函数(比如每秒)。大多数浏览器对使用这些计时器总是说得多,做得少,主要是因为 javascript 语言是单线程的语言。如果您要求的时间间隔为 1 秒,那么获得的回调时间间隔可能是 1 秒、1.2 秒、9 秒或任何其他时间。

  绝对不需要使用计时器的一种情况就是等待 ajax 请求的完成。以 清单 1 为例。

  清单 1. antipat1a_polling.html

<html><script>
var req = null;

function loadurl( url ) {
  if(window.xmlhttprequest) {
    try { req = new xmlhttprequest();
    } catch(e) { req = false; }
  } else if(window.activexobject) {
    try { req = new activexobject('msxml2.xmlhttp');
    } catch(e) {
    try { req = new activexobject('microsoft.xmlhttp');
    } catch(e) { req = false; }
  } }
  if(req) {
    req.open('get', url, true);
    req.send('');
  }
}

window.setinterval( function watchreq() {
    if ( req != null && req.readystate == 4 && req.status == 200 ) {
      var dobj = document.getelementbyid( 'htmldiv' );
      dobj.innerhtml = req.responsetext;
      req = null;
   }
 }, 1000 );

var url = window.location.tostring();
url = url.replace( /antipat1a_polling.html/, 'antipat1_content.html' );
loadurl( url );
</script><body>
dynamic content is shown between here:<br/>
<div id="htmldiv" style="border:1px solid black;padding:10px;">
</div>and here.</body></html>

  在进行 setinterval 调用之前,所有一切看上去都工作得不错。这个调用将设置监视请求状态的计时器,然后使用下载的资源设置页面内容。

  我将展示一个更好的解决方案,用来计算出什么时候请求能够完成。同时,清单 2 展示了页面正在请求的文件。

  清单 2. antipat1_content.html

<b>hello there</b>

  同时 图 1 显示了在我的浏览器中看到的页面。

  图 1. 放置在 html 文档中的内容

放置在 html 文档中的内容

  所以,您可能会问自己,“它现在可以工作,不是吗?如果没有出现故障的话,为什么要修复呢?” 实际上已经出现故障了,因为程序运行得非常慢。计时器将时间间隔设置为 1 秒,随着时间的流逝,请求完全超过了时间间隔。所以,您将看到页面首先出现一个空的框,然后再等待一秒钟,忽然出现大量的内容。多么糟糕!

  如何解决呢?ajax 天生就是异步的。难道不需要进行轮询循环就能查看何时完成请求吗?

……

扫描关注微信公众号