在编写ASP程序时,通常为了提高ASP程序的运行效率及减少对数据库的连接和查询,会使用缓存技术来缓存一些需要从数据库读取的数据。而在ASP中实现缓存的方法常用的就是使用Application对象。在编写ASP程序时,我们有两种语言可以选择,分别是VBScript和JScript。
在使用VBScript时,我们可以用Application缓存数组来实现缓存,例:
- Dim?rs,arr
- rs.Open?conn,sql,1,1
- arr=rs.GetRows()
- Application.Lock()
- Application(“cache”)=arr
- Applicatoin.UnLock()
在VBScript里,数组是可以存到Application对象里的,但是如果ASP的语言选择为JScript的话,那么就有些不妙了,我们在使用Application储存一个数组时,会出现以下错误:
Application?object,?ASP?0197?(0x80004005)
Disallowed?object?use
Cannot?add?object?with?apartment?model?behavior?to?the?application?intrinsic?object.
在微软的知识库可以找到具体原因如下:
JScript?arrays?are?considered?to?be?”Apartment”?COM?components.?Only?Component?Object?Model?(COM)?components?that?aggregate?the?Free?Threaded?Marshaler?(FTM)?can?be?assigned?to?Application?scope?within?an?Internet?Information?Server?(IIS)?5.0?ASP?page.?Because?an?”Apartment”?component?cannot?aggregate?the?FTM?(it?cannot?allow?a?direct?pointer?to?be?passed?to?its?clients,?unlike?a?”Both?with?FTM”?object),?JScript?arrays?do?not?aggregate?the?FTM.?Therefore,?JScript?arrays?cannot?be?assigned?to?Application?scope?from?an?ASP?page.
以上描述引用自:PRB:?Error?When?You?Store?a?JScript?Array?in?Application?Scope?in?IIS?5.0
因此,为了解决这个问题,在Google里找了一大会,终于找到了一篇文章《Application对象的Contents和StaticObjects做Cache的一些结论》,解决了这个问题,方法就是使用Application.StaticObject存放一个Scripting.Dictionary对象,然后再使用Scripting.Dictionary对象来存放需要缓存的数据。
据此,写了一个操作缓存的类,实现put、get、remove和clear方法,使用之前,需要在global.asa中添加一个object:
- <object?id=”xbsCache”?runat=”server”?scope=”Application”?progid=”Scripting.Dictionary”></object>
类的实现如下:
- <script?language=”JScript”?runat=”server”>
- /**
- ?Title:?cache?operate?class
- ?Description:?operate?system?cache
- ?@Copyright:?Copyright?(c)?2007
- ?@Author:?xujiwei
- ?@Website:?http://www.xujiwei.cn/
- ?@Version:?1.0
- ?@Time:?2007-06-29?12:03:45
- **/
- var?xbsCache?=?{
- ????get:?function(key)?{
- ????????return?Application.StaticObjects(“xbsCache”).Item(“Cache.”+key);
- ????},
- ????put:?function(key,?data)?{
- ????????Application.Lock();
- ????????Application.StaticObjects(“xbsCache”).Item(“Cache.”+key)=data;
- ????????Application.UnLock();
- ????},
- ????remove:?function(key)?{
- ????????Application.Lock();
- ????????Application.StaticObjects(“xbsCache”).Remove(“Cache.”+key);
- ????????Application.UnLock();
- ????},
- ????clear:?function()?{
- ????????Application.Lock();
- ????????Application.StaticObjects(“xbsCache”).RemoveAll();
- ????????Application.UnLock();
- ????}
- }
- </script>
如此,就完成了ASP中使用JScript时的缓存实现。
================================================================================
在JScript中实现了基于Application.StaticObjects的缓存技术,并且实现一个类用于缓存的操作,但在实际使用过程中仍需要注意一些问题。
在JScript的函数中,如果参数类型是number或者string,那么是按值传递的,但如果是object,那么就是按引用传递了。另外,数组在JScript中也是作为一个特殊的对象对待,因此,数组的类型也是object,同样是按引用传递的。
使用xbsCache类进行保存和获取数据操作即put和get时,不管是按值还是按引用,都没有问题,但是在使用过程中,对数据操作的效果由数据类型不同而不同。
如果数据是number或string类型的,那么在get数据时,返回值是按值的,也就是说,我们得到的数据是缓存数据的一份copy,对变量的操作并不会影响到缓存中的数据,例:
- //?code?by?xujiwei
- //?from?www.xujiwei.cn
- var?myname=”my?name?is?xujiwei”;
- xbsCache.put(“name”,myname);
- //?从缓存中获取name,值为”my?name?is?xujiwei”
- var?myname2=xbsCache.get(“name”);
- //?给myname2赋值”xujiwei”
- myname2=”xujiwei”;
- //?从缓存中获取name,值仍为”my?name?is?xujiwei”
- var?myname3=xbsCache.get(“name”);
但是在数据类型为object的情况下,我们就需要注意,在从缓存中获取数据之后,我们得到的只是一个指向缓存数据的引用而已,并不是缓存数据的copy,因此,对数据的修改是直接影响到缓存的,例:
- //?code?by?xujiwei
- //?from?www.xujiwei.cn
- //?构建一个myname对象,具有属性Name,值为”my?name?is?xujiwei”
- var?myname={Name:”my?name?is?xujiwei”};
- xbsCache.put(“name”,myname);
- //?从缓存中获取name,Name属性值为”my?name?is?xujiwei”
- var?myname2=xbsCache.get(“name”);
- //?给myname2赋值”xujiwei”
- myname2.Name=”xujiwei”;
- //?从缓存中获取name,Name属性值变为”xujiwei”
- var?myname3=xbsCache.get(“name”);
由于数据类型不同而引起的这两种情况,在使用缓存时需要分别对待,如果需要会对缓存中object类型数据进行修改,应该设置一个标志变量,以免对数据重复进行修改,从而破坏了数据的准确性。
最新评论
写的挺好的
有没有兴趣翻译 impatient js? https://exploringjs.com/impatient-js/index.html
Flexbox playground is so great!
感谢总结。
awesome!
这个好像很早就看到类似的文章了
比其他的教程好太多了
柯理化讲的好模糊…没懂