javascript如何同步调用webservice? 同步?这个对ajax来说是挺难办的.不过你可以将调用封装,然后做个监听来模仿一下同步吧. 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 var superH=function(){this.start=false;this.returnvalue="";this.doMul=function(){ service.useService("Multi.asmx?wsdl","DoMultiService"); var parm1 = Form1.all.mul1.value; var parm2 = Form1.all.mul2.value; this.start=true; service.DoMultiService.callService(this.setvalue,"DoMulti",parm1,parm2); } this.setvalue=fucntion(result){ if (!result.error) { this.returnvalue=result.value; } else { this.returnvalue=result.errorDetail.string; } } this.getretValue=function(){ if(!this.start){this.doMul();} if(this.returnvalue!=""){ Form1.all.retValue.value=this.returnvalue; }else{ window.setTimeout(this.getretValue,10); }return;} } <INPUT style="WIDTH: 50px" onclick='superH.getretValue();' type=button value="="> 我觉得七楼zowell的代码,应该也是异步的,不是同步的。 我自己封装的一个Ajax操作类,支持同步smAjax.js/* ---- 超轻量级Ajax功能封装0.1版 不需要其他的js库支持 --- maple2008于2007.7 (代码无偿使用,请保留作者信息) 更新日志: 2008.05.25 对回收XmlRequest对象作了调整,可以根据this.xmlHttpRequest判断当前是否正在执行读取。*/function ajaxInfo(_url){ var T = this; this.method = "GET"; //GET | POST | HEAD this.url = (_url?_url:null); //请求地址 this.asynch = true; //异步 this.container= null; //容器,接收返回的数据 this.loadFunc = null; //正在载入调用 this.okFunc = null; //载入成功调用 this.errFunc = null; //载入失败调用 this.sendContent = null; //send发送的内容 this.requestType = "TEXT"; //"TEXT" | "XML" | "ALLHEADER" | "HEADER" this.contentType = null //设置请求的: Content-Type this.headerName = null; //请求的头部名称 this.xmlHttpRequest = null; //保存XMLHttpRequest请求对象 //赋予T.xmlHttpRequest一个可用的httpXMLRequest对象 this.prepareXMLHttpRequest = function() { if(T.xmlHttpRequest)//T.xmlHttpRequest不为空,则直接重置后返回. { T.xmlHttpRequest.abort(); return ; } if(ajaxInfo.prototype.XmlRequestArray.length>0) //有空闲的xmlRequest对象,取一个赋给T.xmlHttpRequest { T.xmlHttpRequest = ajaxInfo.prototype.XmlRequestArray.pop(); } else //没有空闲的xmlRequest对象,建立一个赋给T.xmlHttpRequest { var objXMLHttp; if (window.XMLHttpRequest) { objXMLHttp = new XMLHttpRequest(); } else { var MSXML=['MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP']; for(var n = 0; n < MSXML.length; n ++) { try { objXMLHttp = new ActiveXObject(MSXML[n]); break; } catch(e){} } } T.xmlHttpRequest = objXMLHttp; } T.xmlHttpRequest.abort();//重置 } //根据请求类别,填充数据 this.fill = function() { if(T.requestType=="XML") { T.container= T.xmlHttpRequest.responseXML; } else if(T.requestType=="TEXT") { T.container = T.xmlHttpRequest.responseText; } else if(T.requestType=="ALLHEADER") { T.container = T.xmlHttpRequest.getAllResponseHeaders(); } else if(T.requestType=="HEADER") { T.container = T.xmlHttpRequest.getResponseHeader(T.headerName); } else { T.container = "不支持的请求类型."; } } //发送请求,填充T.container,可以带一个url参数. this.get = function (_url) { //超时机制 if(T.xmlHttpRequest && ajaxInfo.prototype.useTime<ajaxInfo.prototype.timeOut) { setTimeout(function(){T.get(_url)},100); ajaxInfo.prototype.useTime+=100; return; } ajaxInfo.prototype.useTime = 0; T.url = _url || T.url; if(T.url=="" || T.url==null) { //确保有请求地址,可根据需要修改,弹出错误提示或抛出异常? alert(ajaxInfo.prototype.NoUrl); return; } T.prepareXMLHttpRequest(); if(!T.xmlHttpRequest) { //确保建立请求对象,根据需要修改,弹出错误提示或抛出异常? alert(ajaxInfo.prototype.NoXMLHttpRequest); return; } if(T.asynch) { //设置异步操作 T.xmlHttpRequest.onreadystatechange = function() { switch (T.xmlHttpRequest.readyState) { /* 0 - (未初始化)还没有调用send()方法 1 - (载入)已调用send()方法,正在发送请求 2 - (载入完成)send()方法执行完成,已经接收到全部响应内容 3 - (交互)正在解析响应内容 4 - (完成)响应内容解析完成,可以在客户端调用了 */ case 0: case 1: case 2: case 3: if(T.loadFunc) { T.loadFunc(T.xmlHttpRequest.readyState); } break; case 4: if(T.xmlHttpRequest.status==200) { T.fill(); if(T.okFunc) { T.okFunc(T.xmlHttpRequest.status); } } else { if(T.errFunc) { T.errFunc(T.xmlHttpRequest.status); } } //回收XmlRequest对象 ajaxInfo.prototype.XmlRequestArray.push(T.xmlHttpRequest); T.xmlHttpRequest = null; break; default: alert("未处理状态."); break; } } } T.xmlHttpRequest.open(T.method,T.url,T.asynch);//发送请求 if(T.contentType) { T.xmlHttpRequest.setRequestHeader("Content-Type", T.contentType); } T.xmlHttpRequest.send(T.sendContent); if(!T.asynch)//同步请求操作(兼容firefox,firefox在同步的情况下无法正常调用onreadystatechange设定的函数) { T.fill(); ajaxInfo.prototype.XmlRequestArray.push(T.xmlHttpRequest); //回收XmlRequest对象 T.xmlHttpRequest = null; } }}ajaxInfo.prototype.NoXMLHttpRequest = "您的浏览器不支持XMLHttpRequest,请升级浏览器以便正常访问";ajaxInfo.prototype.NoUrl = "请求地址为空,操作失败.";//用于POST数据时,将 o.contentType = ajaxInfo.prototype.ContenTypeForm, 这个太长了,不好记,当作常量放在这里 :) ajaxInfo.prototype.ContenTypeForm = "application/x-www-form-urlencoded"; ajaxInfo.prototype.timeOut = 5000;//超时时间ajaxInfo.prototype.useTime = 0; //耗时ajaxInfo.prototype.XmlRequestArray = new Array(); //保存空闲的HttpXMLRequest对象,以便复用同步调用方式:a.txt:一个文本文件,内容随意。testAjax.htm<!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" /> <title>ajax封装测试</title> <script language="javascript" src="smAjax.js"></script></head><body><span id="s1"></span><script language="javascript"> var ai = new ajaxInfo(); ai.asynch = false;//同步设置 ai.okFunc = function(){ document.getElementById("s1").innerHTML += ai.container + "<hr/>";} ai.get("1.txt"); </script></body></html> 网上看到的一个例子:下面分析Sample.htm的内容(取自Msdn):<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><LINK REL="stylesheet" HREF="/workshop/samples/samples.css" TYPE="text/css"><SCRIPT language="JavaScript">var iCallID;var callObj;function init(){// 定位WebService服务位置,并且为该服务制定一个名字// 同一ServiceURl可以指定多个名字,Service为HTM文件中的HTML TAG,可以使用HTML中定义的任何标记service.useService("..\\..\\MathService.asmx?WSDL","MyMath");// 禁用Add按钮.doAddButton.disabled = true;service.onserviceavailable = enableButton();}function enableButton(){doAddButton.disabled = false;}function doAdd(x, y){// 同步调用 // 创建一个 the SOAPHeader objectvar headObj = new Object();// 创建 the call object callObj = service.createCallOptions();callObj.async = false;callObj.params = new Array();callObj.params.a = x;callObj.params.b = y;callObj.funcName = "Add";callObj.SOAPHeader = new Array();callObj.SOAPHeader[0] = headObj;oSPAN.innerText = x + " + " + y + " = ";// 使用回调函数"mathResults"调用iCallID = service.MyMath.callService(mathResults, callObj);mathResults(iCallID);}function doSubtraction(y, x){// 异步调用,这是系统默认的调用方式(the default)oSPAN.innerText = y + " - " + x + " = ";// 调用Subtract// 使用回调函数"mathResults"调用 iCallID = service.MyMath.callService(mathResults, "Subtract", y, x);}function mathResults(result){// If there is an error, and the call came from the call() in init()if(result.error){// Pull the error information from the event.result.errorDetail propertiesvar xfaultcode = result.errorDetail.code;var xfaultstring = result.errorDetail.string;var xfaultsoap = result.errorDetail.raw;oSPAN.innerText = xfaultcode + " " + xfaultstring + " " + xfaultsoap;}// If there was no errorelse{// Show the arithmeticoSPAN.innerText += result.value;}}</SCRIPT></HEAD><body onload="init()">//设置Div元素绑定WebService服务,在这里可以添加onresult="onWSresult()",在该事件中处理调用结果<div id="service" style="behavior:url(../webservice.htc)"></div><BR><BR>Equation : <SPAN id="oSPAN"></SPAN><BR><BR><BUTTON id="doAddButton" onclick="doAdd(5, 6);">Do Add function of 5 and 6</BUTTON><BUTTON onclick="doSubtraction(6, 5);">Do Subtraction of 6 and 5</BUTTON></body></HTML>------------------------------------------------------------------------------------------------其中有一句“service.onserviceavailable = enableButton();”,如果在我的程序中模仿这个例子,这句可以省略吗?好像没有意义。 其中有一句“service.onserviceavailable = enableButton();”,如果在我的程序中模仿这个例子,这句可以省略吗?好像没有意义。 这个对ajax来说是很容易的,send方法就有个函数来操作同步或异步,但对于.net封装好的ajax来说就不知道怎样下手了 如何在父窗口中关闭所有window.open的子窗口 doSubmit后html:cancel按钮如何变有效???[ 撒分喽!~~~大家先看一下这个怎么做的啊? FF 刷新 父窗体 一个无刷新换css的技术问题! 并非单页面!!!!!!!谢谢高手!!!!!!!! offsetWidth有时为0有时不为0的原因? 困扰很久的firefox关于com的问题 如何实现动态表格对象的创建? 如體得到字體的值... 用javascript怎么去调用系统的Beep(蜂鸣声)! 求文本框只能输入1-100之间数字的正则,和只能输入邮箱格式的正则? javascript如何求组合
var superH=function(){
this.start=false;
this.returnvalue="";
this.doMul=function(){
service.useService("Multi.asmx?wsdl","DoMultiService");
var parm1 = Form1.all.mul1.value;
var parm2 = Form1.all.mul2.value;
this.start=true;
service.DoMultiService.callService(this.setvalue,"DoMulti",parm1,parm2);
}
this.setvalue=fucntion(result){
if (!result.error)
{ this.returnvalue=result.value;
}
else
{
this.returnvalue=result.errorDetail.string;
}
}
this.getretValue=function(){
if(!this.start){this.doMul();}
if(this.returnvalue!=""){
Form1.all.retValue.value=this.returnvalue;
}else{
window.setTimeout(this.getretValue,10);
}
return;
}
}
<INPUT style="WIDTH: 50px" onclick='superH.getretValue();' type=button value="=">
/*
---- 超轻量级Ajax功能封装0.1版 不需要其他的js库支持 ---
maple2008于2007.7
(代码无偿使用,请保留作者信息)
更新日志:
2008.05.25 对回收XmlRequest对象作了调整,可以根据this.xmlHttpRequest判断当前是否正在执行读取。
*/
function ajaxInfo(_url)
{
var T = this;
this.method = "GET"; //GET | POST | HEAD
this.url = (_url?_url:null); //请求地址
this.asynch = true; //异步
this.container= null; //容器,接收返回的数据
this.loadFunc = null; //正在载入调用
this.okFunc = null; //载入成功调用
this.errFunc = null; //载入失败调用
this.sendContent = null; //send发送的内容
this.requestType = "TEXT"; //"TEXT" | "XML" | "ALLHEADER" | "HEADER"
this.contentType = null //设置请求的: Content-Type
this.headerName = null; //请求的头部名称
this.xmlHttpRequest = null; //保存XMLHttpRequest请求对象
//赋予T.xmlHttpRequest一个可用的httpXMLRequest对象
this.prepareXMLHttpRequest = function()
{
if(T.xmlHttpRequest)//T.xmlHttpRequest不为空,则直接重置后返回.
{
T.xmlHttpRequest.abort();
return ;
}
if(ajaxInfo.prototype.XmlRequestArray.length>0) //有空闲的xmlRequest对象,取一个赋给T.xmlHttpRequest
{
T.xmlHttpRequest = ajaxInfo.prototype.XmlRequestArray.pop();
}
else //没有空闲的xmlRequest对象,建立一个赋给T.xmlHttpRequest
{
var objXMLHttp;
if (window.XMLHttpRequest) { objXMLHttp = new XMLHttpRequest(); }
else
{ var MSXML=['MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];
for(var n = 0; n < MSXML.length; n ++)
{
try { objXMLHttp = new ActiveXObject(MSXML[n]); break; }
catch(e){}
}
}
T.xmlHttpRequest = objXMLHttp;
}
T.xmlHttpRequest.abort();//重置
} //根据请求类别,填充数据
this.fill = function()
{
if(T.requestType=="XML")
{
T.container= T.xmlHttpRequest.responseXML;
}
else if(T.requestType=="TEXT")
{
T.container = T.xmlHttpRequest.responseText;
}
else if(T.requestType=="ALLHEADER")
{
T.container = T.xmlHttpRequest.getAllResponseHeaders();
}
else if(T.requestType=="HEADER")
{
T.container = T.xmlHttpRequest.getResponseHeader(T.headerName);
}
else
{
T.container = "不支持的请求类型.";
}
}
//发送请求,填充T.container,可以带一个url参数.
this.get = function (_url)
{
//超时机制
if(T.xmlHttpRequest && ajaxInfo.prototype.useTime<ajaxInfo.prototype.timeOut)
{
setTimeout(function(){T.get(_url)},100);
ajaxInfo.prototype.useTime+=100;
return;
}
ajaxInfo.prototype.useTime = 0;
T.url = _url || T.url;
if(T.url=="" || T.url==null)
{ //确保有请求地址,可根据需要修改,弹出错误提示或抛出异常?
alert(ajaxInfo.prototype.NoUrl);
return;
}
T.prepareXMLHttpRequest();
if(!T.xmlHttpRequest)
{ //确保建立请求对象,根据需要修改,弹出错误提示或抛出异常?
alert(ajaxInfo.prototype.NoXMLHttpRequest);
return;
} if(T.asynch)
{ //设置异步操作
T.xmlHttpRequest.onreadystatechange = function()
{ switch (T.xmlHttpRequest.readyState)
{
/* 0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,可以在客户端调用了
*/
case 0:
case 1:
case 2:
case 3:
if(T.loadFunc)
{
T.loadFunc(T.xmlHttpRequest.readyState);
}
break;
case 4:
if(T.xmlHttpRequest.status==200)
{
T.fill();
if(T.okFunc)
{
T.okFunc(T.xmlHttpRequest.status);
}
}
else
{
if(T.errFunc)
{
T.errFunc(T.xmlHttpRequest.status);
}
}
//回收XmlRequest对象
ajaxInfo.prototype.XmlRequestArray.push(T.xmlHttpRequest);
T.xmlHttpRequest = null;
break;
default:
alert("未处理状态.");
break;
}
}
}
T.xmlHttpRequest.open(T.method,T.url,T.asynch);//发送请求
if(T.contentType)
{
T.xmlHttpRequest.setRequestHeader("Content-Type", T.contentType);
}
T.xmlHttpRequest.send(T.sendContent);
if(!T.asynch)//同步请求操作(兼容firefox,firefox在同步的情况下无法正常调用onreadystatechange设定的函数)
{
T.fill();
ajaxInfo.prototype.XmlRequestArray.push(T.xmlHttpRequest);
//回收XmlRequest对象
T.xmlHttpRequest = null;
}
}
}
ajaxInfo.prototype.NoXMLHttpRequest = "您的浏览器不支持XMLHttpRequest,请升级浏览器以便正常访问";
ajaxInfo.prototype.NoUrl = "请求地址为空,操作失败.";//用于POST数据时,将 o.contentType = ajaxInfo.prototype.ContenTypeForm, 这个太长了,不好记,当作常量放在这里 :)
ajaxInfo.prototype.ContenTypeForm = "application/x-www-form-urlencoded";
ajaxInfo.prototype.timeOut = 5000;//超时时间
ajaxInfo.prototype.useTime = 0; //耗时
ajaxInfo.prototype.XmlRequestArray = new Array(); //保存空闲的HttpXMLRequest对象,以便复用同步调用方式:a.txt:一个文本文件,内容随意。testAjax.htm
<!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" />
<title>ajax封装测试</title>
<script language="javascript" src="smAjax.js"></script>
</head>
<body>
<span id="s1"></span>
<script language="javascript">
var ai = new ajaxInfo();
ai.asynch = false;//同步设置
ai.okFunc = function(){ document.getElementById("s1").innerHTML += ai.container + "<hr/>";}
ai.get("1.txt");
</script>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<LINK REL="stylesheet" HREF="/workshop/samples/samples.css" TYPE="text/css">
<SCRIPT language="JavaScript">
var iCallID;
var callObj;
function init()
{
// 定位WebService服务位置,并且为该服务制定一个名字
// 同一ServiceURl可以指定多个名字,Service为HTM文件中的HTML TAG,可以使用HTML中定义的任何标记
service.useService("..\\..\\MathService.asmx?WSDL","MyMath");
// 禁用Add按钮.
doAddButton.disabled = true;
service.onserviceavailable = enableButton();
}
function enableButton(){
doAddButton.disabled = false;
}
function doAdd(x, y){
// 同步调用 // 创建一个 the SOAPHeader object
var headObj = new Object();
// 创建 the call object
callObj = service.createCallOptions();
callObj.async = false;
callObj.params = new Array();
callObj.params.a = x;
callObj.params.b = y;
callObj.funcName = "Add";
callObj.SOAPHeader = new Array();
callObj.SOAPHeader[0] = headObj;
oSPAN.innerText = x + " + " + y + " = ";
// 使用回调函数"mathResults"调用
iCallID = service.MyMath.callService(mathResults, callObj);
mathResults(iCallID);
}
function doSubtraction(y, x){
// 异步调用,这是系统默认的调用方式(the default)
oSPAN.innerText = y + " - " + x + " = ";
// 调用Subtract
// 使用回调函数"mathResults"调用
iCallID = service.MyMath.callService(mathResults, "Subtract", y, x);
}
function mathResults(result){
// If there is an error, and the call came from the call() in init()
if(result.error){
// Pull the error information from the event.result.errorDetail properties
var xfaultcode = result.errorDetail.code;
var xfaultstring = result.errorDetail.string;
var xfaultsoap = result.errorDetail.raw;
oSPAN.innerText = xfaultcode + " " + xfaultstring + " " + xfaultsoap;
}// If there was no error
else{
// Show the arithmetic
oSPAN.innerText += result.value;
}
}
</SCRIPT>
</HEAD>
<body onload="init()">
//设置Div元素绑定WebService服务,在这里可以添加onresult="onWSresult()",在该事件中处理调用结果
<div id="service" style="behavior:url(../webservice.htc)"></div>
<BR><BR>
Equation : <SPAN id="oSPAN"></SPAN>
<BR><BR>
<BUTTON id="doAddButton" onclick="doAdd(5, 6);">Do Add function of 5 and 6</BUTTON>
<BUTTON onclick="doSubtraction(6, 5);">Do Subtraction of 6 and 5</BUTTON>
</body>
</HTML>
------------------------------------------------------------------------------------------------
其中有一句“service.onserviceavailable = enableButton();”,如果在我的程序中模仿这个例子,这句可以省略吗?好像没有意义。
这个对ajax来说是很容易的,send方法就有个函数来操作同步或异步,但对于.net封装好的ajax来说就不知道怎样下手了