这里举一个委托在异步调用中例子,来说明委托的用法,例子是对XmlHttp的简单封装:
<
script
type
="text/javascript"
>
<!--
/*
* XmlHttp 类
*/
var XmlHttp = function () {
var o = null ;
var readyStateChange = function (processResponseProc) {
if (o.readyState == 4 ) {
if (o.status == 200 ) {
processResponseProc(o.responseText);
} else {
processResponseProc( null );
}
}
};
return {
/*
* init 方法
*
* 返回值
* 如果初始化成功则返回true,否则返回false
*
* 说明
* 初始化XmlHttp对象,
*/
init : function () {
if (o == null ) {
if (window.XMLHttpRequest) {
try {
o = new XMLHttpRequest();
} catch (ex) {
return false ;
}
} else if (window.ActiveXObject) {
try {
o = new ActiveXObject( " Msxml4.XMLHttp " );
} catch (ex) {
try {
o = new ActiveXObject( " Msxml2.XMLHttp " );
} catch (ex) {
try {
o = new ActiveXObject( " Microsoft.XMLHttp " );
} catch (ex) {
return false ;
}
}
}
}
}
return true ;
},
/*
* get 方法
*
* 参数
* url - 要请求的url
* processResponse - 处理返回结果委托
*
* 返回值
* 如果请求发起成功则返回true,否则返回false
*
* 说明
* 发起http请求
*/
get : function (url, processResponse) {
try {
o.open( " GET " , url, true );
o.onreadystatechange = function () { readyStateChange(processResponse); };
o.send();
return true ;
} catch (ex) {
return false ;
}
},
/*
* post 方法
*
* 参数
* url - 要请求的url
* data - 发送的数据,注意这里值必须是urlencode过的
* processResponse - 处理返回结果委托
*
* 返回值
* 如果请求发起成功则返回true,否则返回false
*
* 说明
* 发起post请求
*/
post : function (url, data, processResponse) {
processResponseProc = processResponse;
try {
o.open( " POST " , url, true );
o.onreadystatechange = function () { readyStateChange(processResponse); };
o.setRequestHeader( " Content-Length " , data.length);
o.setRequestHeader( " Content-Type " , " application/x-www-form-urlencoded " );
o.send(data);
return true ;
} catch (ex) {
return false ;
}
}
};
};
var xmlhttp = new XmlHttp();
if (xmlhttp.init()) {
xmlhttp.get( " http://pstgroup.blogspot.com/ " , function (response) {
if (response != null ) {
document.write(response);
}
});
}
// -->
</ script >
<!--
/*
* XmlHttp 类
*/
var XmlHttp = function () {
var o = null ;
var readyStateChange = function (processResponseProc) {
if (o.readyState == 4 ) {
if (o.status == 200 ) {
processResponseProc(o.responseText);
} else {
processResponseProc( null );
}
}
};
return {
/*
* init 方法
*
* 返回值
* 如果初始化成功则返回true,否则返回false
*
* 说明
* 初始化XmlHttp对象,
*/
init : function () {
if (o == null ) {
if (window.XMLHttpRequest) {
try {
o = new XMLHttpRequest();
} catch (ex) {
return false ;
}
} else if (window.ActiveXObject) {
try {
o = new ActiveXObject( " Msxml4.XMLHttp " );
} catch (ex) {
try {
o = new ActiveXObject( " Msxml2.XMLHttp " );
} catch (ex) {
try {
o = new ActiveXObject( " Microsoft.XMLHttp " );
} catch (ex) {
return false ;
}
}
}
}
}
return true ;
},
/*
* get 方法
*
* 参数
* url - 要请求的url
* processResponse - 处理返回结果委托
*
* 返回值
* 如果请求发起成功则返回true,否则返回false
*
* 说明
* 发起http请求
*/
get : function (url, processResponse) {
try {
o.open( " GET " , url, true );
o.onreadystatechange = function () { readyStateChange(processResponse); };
o.send();
return true ;
} catch (ex) {
return false ;
}
},
/*
* post 方法
*
* 参数
* url - 要请求的url
* data - 发送的数据,注意这里值必须是urlencode过的
* processResponse - 处理返回结果委托
*
* 返回值
* 如果请求发起成功则返回true,否则返回false
*
* 说明
* 发起post请求
*/
post : function (url, data, processResponse) {
processResponseProc = processResponse;
try {
o.open( " POST " , url, true );
o.onreadystatechange = function () { readyStateChange(processResponse); };
o.setRequestHeader( " Content-Length " , data.length);
o.setRequestHeader( " Content-Type " , " application/x-www-form-urlencoded " );
o.send(data);
return true ;
} catch (ex) {
return false ;
}
}
};
};
var xmlhttp = new XmlHttp();
if (xmlhttp.init()) {
xmlhttp.get( " http://pstgroup.blogspot.com/ " , function (response) {
if (response != null ) {
document.write(response);
}
});
}
// -->
</ script >
这里get和post方法都是异步调用,都需要传入有一个processResponse参数,这个参数是http返回内容处理函数,也就是我们所说的委托概念,对象内部会在http请求返回后回调该函数来处理返回的内容,委托这个词很形象,XmlHttp类并不知道调用者要对返回结果干些什么,于是就委托给这个传递近来的函数来做。
委托可以很好的降低不同功能之间的耦合,这个例子使用委托就符合Open-Close原则,如果有新的处理返回结果的需求可以很容易扩展,不用改动现有代码,比如我们的新需求是alert返回结果:
var
xmlhttp
=
new
XmlHttp();
if (xmlhttp.init()) {
xmlhttp.get( " http://pstgroup.blogspot.com/ " , function (response) {
if (response != null ) {
alert(response);
}
});
}
if (xmlhttp.init()) {
xmlhttp.get( " http://pstgroup.blogspot.com/ " , function (response) {
if (response != null ) {
alert(response);
}
});
}
委托之所以适合异步调用,是因为异步调用符合委托的使用场景:调用者A调用被调用者B,由于调用过程是异步的,不会立刻返回结果,所以B在拿到返回结果时,有需要依赖于A来处理结果。当在类设计时发现类之间双向互相依赖的情况时,可以考虑使用委托。