这一讲的内容主要是详细的了解Asp.Net Ajax异步通信层的实现方式。课程首先说明了各个类的作用
- WebRequest类:收集(存储)请求信息
- WebRequestExecutor类:发送请求、反馈服务器端回复的结果
- XMLHttpExecutor:封装了XMLHttpRequest的Executor
- WebRequestManager类:用于管理异步通讯层与服务器端的通信
然后说明了一下异步通信层组件协作过程
- 异步通信层组件协作过程
- WebRequestManager确定Executor
- 触发WRM的invokingRequest事件
- 执行Executor的executeRequest方法
2. Executor返回、超时或被取消
- 执行WebRequest的completed方法
- 触发WRM的completedRequest事件
- 触发WebRequest的complete事件
下面是使用Asp.Net Ajax类库的详细调用代码,我会将注释标明。
我们着重关注WebRequest的invoke调用
function Sys$Net$WebRequest$invoke()
...{
//检查调用时是否存在参数,存在就抛出异常
if (arguments.length !== 0) throw Error.parameterCount();
//检查这个WebRequest是否已经被调用了,已经被调用了就抛出异常
if (this._invokeCalled)
...{
throw Error.invalidOperation(Sys.Res.invokeCalledTwice);
}
//使用WebRequestManager这个静态实例的方法executeRequest(执行请求),把当前执行invoke
//的对象作为参数,为什么说WebRequestManager是一个静态实例,因为在注册
//WebRequestManager类之后,有这样一段代码Sys.Net.WebRequestManager = new Sys.Net._WebRequestManager(),
//这说明Sys.Net命名空间里存在一个_WebRequestManager类型,在这个命名空间里有一个叫WebRequestManager实例,他的类型就是_WebRequestManager
Sys.Net.WebRequestManager.executeRequest(this);
//将已经调用标志设置为true
this._invokeCalled = true;
}
...{
//检查调用时是否存在参数,存在就抛出异常
if (arguments.length !== 0) throw Error.parameterCount();
//检查这个WebRequest是否已经被调用了,已经被调用了就抛出异常
if (this._invokeCalled)
...{
throw Error.invalidOperation(Sys.Res.invokeCalledTwice);
}
//使用WebRequestManager这个静态实例的方法executeRequest(执行请求),把当前执行invoke
//的对象作为参数,为什么说WebRequestManager是一个静态实例,因为在注册
//WebRequestManager类之后,有这样一段代码Sys.Net.WebRequestManager = new Sys.Net._WebRequestManager(),
//这说明Sys.Net命名空间里存在一个_WebRequestManager类型,在这个命名空间里有一个叫WebRequestManager实例,他的类型就是_WebRequestManager
Sys.Net.WebRequestManager.executeRequest(this);
//将已经调用标志设置为true
this._invokeCalled = true;
}
上面这段代码,我们着重关注WebRequestManager的executeRequest(WebRequest request)方法
function Sys$Net$_WebRequestManager$executeRequest(webRequest)
...{
//校验参数是否时WebRequest类型
var e = Function._validateParams(arguments, [...{name: "webRequest", type: Sys.Net.WebRequest}]);
if (e) throw e;
//得到webRequest的执行者对象
var executor = webRequest.get_executor();
//如果存在执行者,我们在客户端调用没有设置webRequest的执行者
//运行到这里应该进入这个if判断
if (!executor)
...{
//如果WebRequest对象不存在执行者
var failed = false;
try
...{
//得到WebRequestManger对象的默认执行者类型
var executorType = eval(this._defaultExecutorType);
//生成这个执行者对象,这个对象实际上就是XmlHttpExecutor
//XmlHttpExecutor实际上是继承与WebRequestExecutor类
executor = new executorType();
}
catch (e)
...{
failed = true;
}
//如果执行失败,或者执行者没有继承WebRequestExecutor类,就是说不是WebRequestExecutor实例
//或者executor为空,那么抛出异常
if (failed || !Sys.Net.WebRequestExecutor.isInstanceOfType(executor) || !executor)
...{
throw Error.argument("defaultExecutorType", String.format(Sys.Res.invalidExecutorType, this._defaultExecutorType));
}
//设置WebRequest的执行者
webRequest.set_executor(executor);
}
//如果执行者取消了请求,那么就直接返回
if (executor.get_aborted())
...{
return;
}
//生成一个NetworkReuqestEventArgs参数对象,用webRequest最为参数
var evArgs = new Sys.Net.NetworkRequestEventArgs(webRequest);
//得到invokingRequest事件的事件委托
var handler = this._get_eventHandlerList().getHandler("invokingRequest");
//如果存在这个事件委托,那么就调用这个事件委托
if (handler)
...{
handler(this, evArgs);
}
//如果外部事件委托执行没有取消执行
if (!evArgs.get_cancel())
...{
//调用执行者executor的executeRequest()(执行请求方法)
executor.executeRequest();
}
}
...{
//校验参数是否时WebRequest类型
var e = Function._validateParams(arguments, [...{name: "webRequest", type: Sys.Net.WebRequest}]);
if (e) throw e;
//得到webRequest的执行者对象
var executor = webRequest.get_executor();
//如果存在执行者,我们在客户端调用没有设置webRequest的执行者
//运行到这里应该进入这个if判断
if (!executor)
...{
//如果WebRequest对象不存在执行者
var failed = false;
try
...{
//得到WebRequestManger对象的默认执行者类型
var executorType = eval(this._defaultExecutorType);
//生成这个执行者对象,这个对象实际上就是XmlHttpExecutor
//XmlHttpExecutor实际上是继承与WebRequestExecutor类
executor = new executorType();
}
catch (e)
...{
failed = true;
}
//如果执行失败,或者执行者没有继承WebRequestExecutor类,就是说不是WebRequestExecutor实例
//或者executor为空,那么抛出异常
if (failed || !Sys.Net.WebRequestExecutor.isInstanceOfType(executor) || !executor)
...{
throw Error.argument("defaultExecutorType", String.format(Sys.Res.invalidExecutorType, this._defaultExecutorType));
}
//设置WebRequest的执行者
webRequest.set_executor(executor);
}
//如果执行者取消了请求,那么就直接返回
if (executor.get_aborted())
...{
return;
}
//生成一个NetworkReuqestEventArgs参数对象,用webRequest最为参数
var evArgs = new Sys.Net.NetworkRequestEventArgs(webRequest);
//得到invokingRequest事件的事件委托
var handler = this._get_eventHandlerList().getHandler("invokingRequest");
//如果存在这个事件委托,那么就调用这个事件委托
if (handler)
...{
handler(this, evArgs);
}
//如果外部事件委托执行没有取消执行
if (!evArgs.get_cancel())
...{
//调用执行者executor的executeRequest()(执行请求方法)
executor.executeRequest();
}
}
下面关注XmlHttpExecutor的executeRequest()方法
function Sys$Net$XMLHttpExecutor$executeRequest()
...{
//检测参数个数,如果不等于0,那么抛出异常
if (arguments.length !== 0) throw Error.parameterCount();
//得到WebRequest对象,用来将保存的信息传递出去
//在WebRequest对象的set_executor方法里,已经将执行者对应的
//WebRequest对象设置到执行者中,并且set_executor方法是基类
//WebRequestExecutor类的方法,这里调用的是基类的方法
this._webRequest = this.get_webRequest();
//判断这个执行者是否已经开始传递数据,如果已经开始传递,那么抛出异常
if (this._started)
...{
throw Error.invalidOperation(String.format(Sys.Res.cannotCallOnceStarted, 'executeRequest'));
}
//判断webRequest对象是否为空,为空就抛出异常
if (this._webRequest === null)
...{
throw Error.invalidOperation(Sys.Res.nullWebRequest);
}
//得到WebReuqest对象的body
var body = this._webRequest.get_body();
//得到WebReuqest对象的header集合
var headers = this._webRequest.get_headers();
//这一段代码是标准的ajax应用
//实例化一个xmlHttpRequest对象
this._xmlHttpRequest = new XMLHttpRequest();
//给定状态改变的回调函数
this._xmlHttpRequest.onreadystatechange = this._onReadyStateChange;
//得到WebReuqest对象的请求动作
var verb = this._webRequest.get_httpVerb();
//指定请求的连接和动作,并表明是一个异步传输
this._xmlHttpRequest.open(verb, this._webRequest.getResolvedUrl(), true );
if (headers)
...{
//遍历header集合
for (var header in headers)
...{
var val = headers[header];
//如果header不是js函数
if (typeof(val) !== "function")
//将header设置到xmlHttpRequest对象的请求头里
this._xmlHttpRequest.setRequestHeader(header, val);
}
}
//判断动作是否是post
if (verb.toLowerCase() === "post")
...{
//通过设定的头,来设置传送内容的类型
if ((headers === null) || !headers['Content-Type'])
...{
this._xmlHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
if (!body)
...{
body = "";
}
}
//得到WebReuqest对象的超时时间
var timeout = this._webRequest.get_timeout();
//如果设置了超时时间
if (timeout > 0)
...{
...{
//检测参数个数,如果不等于0,那么抛出异常
if (arguments.length !== 0) throw Error.parameterCount();
//得到WebRequest对象,用来将保存的信息传递出去
//在WebRequest对象的set_executor方法里,已经将执行者对应的
//WebRequest对象设置到执行者中,并且set_executor方法是基类
//WebRequestExecutor类的方法,这里调用的是基类的方法
this._webRequest = this.get_webRequest();
//判断这个执行者是否已经开始传递数据,如果已经开始传递,那么抛出异常
if (this._started)
...{
throw Error.invalidOperation(String.format(Sys.Res.cannotCallOnceStarted, 'executeRequest'));
}
//判断webRequest对象是否为空,为空就抛出异常
if (this._webRequest === null)
...{
throw Error.invalidOperation(Sys.Res.nullWebRequest);
}
//得到WebReuqest对象的body
var body = this._webRequest.get_body();
//得到WebReuqest对象的header集合
var headers = this._webRequest.get_headers();
//这一段代码是标准的ajax应用
//实例化一个xmlHttpRequest对象
this._xmlHttpRequest = new XMLHttpRequest();
//给定状态改变的回调函数
this._xmlHttpRequest.onreadystatechange = this._onReadyStateChange;
//得到WebReuqest对象的请求动作
var verb = this._webRequest.get_httpVerb();
//指定请求的连接和动作,并表明是一个异步传输
this._xmlHttpRequest.open(verb, this._webRequest.getResolvedUrl(), true );
if (headers)
...{
//遍历header集合
for (var header in headers)
...{
var val = headers[header];
//如果header不是js函数
if (typeof(val) !== "function")
//将header设置到xmlHttpRequest对象的请求头里
this._xmlHttpRequest.setRequestHeader(header, val);
}
}
//判断动作是否是post
if (verb.toLowerCase() === "post")
...{
//通过设定的头,来设置传送内容的类型
if ((headers === null) || !headers['Content-Type'])
...{
this._xmlHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
if (!body)
...{
body = "";
}
}
//得到WebReuqest对象的超时时间
var timeout = this._webRequest.get_timeout();
//如果设置了超时时间
if (timeout > 0)
...{