首页 » 编写高质量代码:改善JavaScript程序的188个建议 » 编写高质量代码:改善JavaScript程序的188个建议全文在线阅读

《编写高质量代码:改善JavaScript程序的188个建议》建议148:使用本地存储数据

关灯直达底部

除了依赖浏览器处理缓存之外,还可以用手工方法直接存储那些从服务器收到的响应报文。可将响应报文存放在一个对象中,以URL为键值对它进行索引。以下是一个XHR封装,它首先检查一个URL此前是否被取用过。


var localCache={};

function xhrRequest(url,callback){

if(localCache[url]){

callback.success(localCache[url]);

return;

}

var req=createXhrObject;

req.onerror=function{

callback.error;

};

req.onreadystatechange=function{

if(req.readyState==4){

if(req.responseText===''||req.status=='404'){

callback.error;

return;

}

localCache[url]=req.responseText;

callback.success(req.responseText);

}

};

req.open("GET",url,true);

req.send(null);

}


当然,设置一个Expires头是更好的解决方案,实现起来比较容易,而且其缓存内容可以跨页面或跨对话。而一个手工缓存可以利用程序废止缓存内容并获取新的数据。设想一种情况,为每个请求缓存数据,用户可能触发某些动作导致一个或多个响应报文作废。在这种情况下从缓存中删除报文十分简单:


delete localCache['/user/friendlist/'];

delete localCache['/user/contactlist/'];


本地缓存也可很好地工作于移动设备上。此类设备上的浏览器缓存小或根本不存在,手工缓存成为避免不必要请求的最佳选择。

值得注意的是,在大部分XHR技术中要用到流功能。通过监听readyState=3,可以在一个大的响应报文没有完全接收之前就开始解析它,这时可以实时处理报文片断。这也是MXHR能够大幅度提高性能的原因之一。不过大多数JavaScript库不允许直接访问readystatechange事件,这意味着必须等待整个响应报文接收完才能使用它。

直接使用XMLHttpRequest对象并非像看起来那么不好。除一些个别行为之外,所有主流浏览器的最新版本均以同样方式支持XMLHttpRequest对象,均可访问不同的readyState。要支持老版本的IE,只需要多加几行代码。下面例子中的函数返回一个XHR对象,可以直接调用这个对象。


function createXhrObject{

var msxml_progid=['MSXML2.XMLHTTP.6.0',

'MSXML3.XMLHTTP',

'Microsoft.XMLHTTP',

'MSXML2.XMLHTTP.3.0'];

var req;

try{

req=new XMLHttpRequest;

}catch(e){

for(var i=0,len=msxml_progid.length;i<len;++i){

try{

req=new ActiveXObject(msxml_progid[i]);

break;

}catch(e2){

}

}

}finally{

return req;

}

}


此函数首先尝试支持readyState=3的XMLHttpRequest,然后回落到那些不支持此状态的版本中。直接操作XHR对象减少了函数开销,进一步提高了性能。只是放弃使用Ajax库,可能会在极少数的浏览器上遇到一些问题。