(四) DWR JS工作流程

 

DWR工作流程简单来说,

例子中jsp中引入/DWRDemo/dwr/interface/dwrDate.js文件中,方法都是调用 _execute方法,框架封装了_sendData发送ajax请求,后台返回JS代码,前端解析,在调用_remoteHandleCallback方法,执行我们写的回调方法;

dwrDate.getYear = function(callback) {
  dwr.engine._execute(dwrDate._path, 'dwrDate', 'getYear', callback);
}
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <!-- 这三个js导入项必不可少 -->
    <!-- 每一个对象都会有以一个对象为名称的那个js库 -->
    <!-- Dwr 引擎库 -->
      <script type='text/javascript' src='/DWRDemo/dwr/engine.js'></script>
      <!-- Dwr 工具库 -->
      <script type='text/javascript' src='/DWRDemo/dwr/util.js'></script>
	 <script type="text/javascript" src="/DWRDemo/dwr/interface/dwrDate.js"></script>
    <script>
        window.onload = function(){            
            dwrDate.getYear(function(data){
               
                document.getElementById("showTime").innerHTML += 1900 + data + " 年 ";
            });
            dwrDate.getMonth(function(data){
                document.getElementById("showTime").innerHTML += 1 + data + " 月 ";
            });
        };

    </script>
</head>
<body>
<div id="showTime">当前时间:</div>

</body>
</html>

记录下我今天分析的代码:

1.singleShot我理解为一个控制批量发送请求的标志位,true表示不批量发送;
2.arguments参数为方法传入的参数
3.所有_execute()方法入参由dwr自动生成,最后一个参数默认为回调的方法,存储在callData的callback属性中,也会保存在handlers[0]的callback属性里,后面回调就是调的这个callback

4.传递的参数中包含这样的参数

c0-scriptName=dwrDate
c0-methodName=getYear
c0-id=0

不使用批量发送的话每次参数都以c0-开头,因为每次发送都会new一个新的batch对象,callCount都会从0开始重新增加

 

dwr.engine._execute = function(path, scriptName, methodName, vararg_params) {
  var singleShot = false;
  if (dwr.engine._batch == null) {
    dwr.engine.beginBatch();
    singleShot = true;
  }
  var batch = dwr.engine._batch;
  // To make them easy to manipulate we copy the arguments into an args array
  var args = [];
  for (var i = 0; i < arguments.length - 3; i++) {
    args[i] = arguments[i + 3];
  }
  // All the paths MUST be to the same servlet
  if (batch.path == null) {
    batch.path = path;
  }
  else {
    if (batch.path != path) {
      dwr.engine._handleError(batch, { name:"dwr.engine.multipleServlets", message:"Can't batch requests to multiple DWR Servlets." });
      return;
    }
  }
  // From the other params, work out which is the function (or object with
  // call meta-data) and which is the call parameters
  var callData;
  var lastArg = args[args.length - 1];
  if (typeof lastArg == "function" || lastArg == null) callData = { callback:args.pop() };
  else callData = args.pop();

  // Merge from the callData into the batch
  dwr.engine._mergeBatch(batch, callData);
  batch.handlers[batch.map.callCount] = {
    exceptionHandler:callData.exceptionHandler,
    callback:callData.callback
  };

  // Copy to the map the things that need serializing
  var prefix = "c" + batch.map.callCount + "-";
  batch.map[prefix + "scriptName"] = scriptName;
  batch.map[prefix + "methodName"] = methodName;
  batch.map[prefix + "id"] = batch.map.callCount;
  for (i = 0; i < args.length; i++) {
    dwr.engine._serializeAll(batch, [], args[i], prefix + "param" + i);
  }

  // Now we have finished remembering the call, we incr the call count
  batch.map.callCount++;
  if (singleShot) dwr.engine.endBatch();
};

createBatch之后singleShot已经变为true,进入endBatch方法:

endBatch()方法

首先进行了一些校验工作,dwr.engine._batch不能为空、batch.map.callCount不能为零,如果传入了参数options,options是个对象,支持参数有:rpcType、 httpMethod、async、timeout、errorHandler,、warningHandler、textHtmlHandler,请求消息头、方法参数等,这样可以实现局部的个性化,其他方法调用不会引起误会。_ordered属性是用来控制是否严格按照顺序来发送请求得到响应;通过_sendData(batch)发送ajax请求。

 

dwr.engine.endBatch = function(options) {
  var batch = dwr.engine._batch;
  if (batch == null) {
    dwr.engine._handleError(null, { name:"dwr.engine.batchNotBegun", message:"No batch in progress" });
    return;
  }
  dwr.engine._batch = null;
  if (batch.map.callCount == 0) return;

  // The hooks need to be merged carefully to preserve ordering
  if (options) dwr.engine._mergeBatch(batch, options);

  // In ordered mode, we don't send unless the list of sent items is empty
  if (dwr.engine._ordered && dwr.engine._batchesLength != 0) {
    dwr.engine._batchQueue[dwr.engine._batchQueue.length] = batch;
  }
  else {
    dwr.engine._sendData(batch);
  }
};

sendData方法太占篇幅就不贴代码了;

_sendData方法主要就是ajax发送请求,置于推送模式,暂时没能力分析,ajax异步请求状态改变事件为dwr.engine._stateChange(); 接收到响应类似这样;通过

if (toEval != null) toEval = toEval.replace(dwr.engine._scriptTagProtection, "");
 dwr.engine._eval(toEval);

eval函数调用了eval()方法来解析响应的JS字符串,并执行该方法dwr.engine._remoteHandleCallback,里面就会执行我们写入的回调函数了

throw 'allowScriptTagRemoting is false.';
//#DWR-INSERT
//#DWR-REPLY
dwr.engine._remoteHandleCallback('0','0',118);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值