javascript - jQuery如何才能获得同步执行,而不是异步的 ajax请求?

  显示原文与译文双语对照的内容

我有一个JavaScript小部件,它提供标准扩展点。 其中一个是 beforecreate 函数。 它应该返回 false 以防止创建项目。

我使用jQuery在这里函数中添加了一个AJAX调用:


beforecreate: function (node, targetNode, type, to) {
 jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value),

 function (result) {
 if (result.isOk == false) alert(result.message);
 });
}

但我想阻止我的小部件创建的项目,所以我应该返回 false mother-function,回调。 是否可以使用jQuery或者任何其他API执行同步AJAX请求? 谢谢。

时间:

Jquery文档列表中: 你指定异步选项同步ajax请求。 然后你的回调可以在你的mom函数继续之前设置一些数据。

下面是你的代码如建议的那样显示:


beforecreate: function(node,targetNode,type,to) {
 jQuery.ajax({
 url: 'http://example.com/catalog/create/' 
 + targetNode.id 
 + '?name=' 
 + encode(to.inp[0].value),
 success: function(result) {
 if(result.isOk == false)
 alert(result.message);
 },
 async: false
 }); 
}

你可以通过调用以下方法将jquery安装程序的AJAX置于同步模式


jQuery.ajaxSetup({async:false});

然后使用 jquery 。获取你的ajax调用。get 。 ) ;

然后再把它打开一次


jQuery.ajaxSetup({async:true});

我猜这是 @Adam 建议的一样但是可能有用的人,并想要重新配置他们 jQuery.get() 或者 jQuery.post() 更复杂的jQuery.ajax() 语法

很好的解决方案我注意到当我试图实现它时,如果我在success子句中返回一个值,它就会被作为未定义的。 我必须将它存储在变量中并返回变量。 这是我提出的方法:


function getWhatever() {
//strUrl is whatever URL you need to call
 var strUrl ="", strReturn ="";

 jQuery.ajax({
 url: strUrl,
 success: function(html) {
 strReturn = html;
 },
 async:false
 });

 return strReturn;
}

所有这些答案小姐,做一个ajax调用 async:false 会导致浏览器挂在ajax请求完成之前。 使用流量控制库可以解决这里问题,而无需挂起浏览器。 下面是一个带有 Frame.js的示例:


beforecreate: function(node,targetNode,type,to) { 

 Frame(function(next)){ 

 jQuery.get('http://example.com/catalog/create/', next);

 });
 Frame(function(next, response)){ 

 alert(response);
 next();

 });
 Frame.init();
}


function getURL(url){
 return $.ajax({
 type:"GET",
 url: url,
 cache: false,
 async: false
 }).responseText;
}


//example use
var msg=getURL("message.php");
alert(msg);

请记住,如果你正在执行 cross-domain ajax调用( 使用 JSONP编辑器) - 你不能异步执行,"异步"标志将被jQuery忽略。


$.ajax({
 url:"testserver.php",
 dataType: 'jsonp',//jsonp
 async: false//IGNORED!!
});

对于 JSONP-calls,你可以使用:

  1. Ajax-call到你自己的域- 并执行cross-domain调用 server-side
  2. 将代码更改为异步工作
  3. 使用"函数排序器"库像 Frame.js (这回答)
  4. 阻止用户界面而不是阻塞执行( 这里应答 ) ( 我最喜欢的方式)

我使用了Carcione给出的答案并修改它来使用 JSON 。


 function getUrlJsonSync(url){

 var jqxhr = $.ajax({
 type:"GET",
 url: url,
 dataType: 'json',
 cache: false,
 async: false
 });

//'async' has to be 'false' for this to work
 var response = {valid: jqxhr.statusText, data: jqxhr.responseJSON};

 return response;
} 

function testGetUrlJsonSync()
{
 var reply = getUrlJsonSync("myurl");

 if (reply.valid == 'OK')
 {
 console.dir(reply.data);
 }
 else
 {
 alert('not valid');
 } 
}

我添加了数据类型'json' 和改变了 。responsetext, responseJSON

我还使用返回对象的 statusText属性检索状态。 注意,这是Ajax响应的状态,而不是JSON是否有效。

后端必须以正确的( well-formed ) JSON返回响应,否则返回的对象将被未定义。

在回答原始问题时,需要考虑两个方面。 一个是告诉Ajax同步执行( 通过设置位异步: false ),而另一个通过函数调用的调用返回返回响应,而不是返回回调函数。

我还尝试了 POST,它工作了。

我更改了get发布 to,并添加了英镑数据: postdata


function postUrlJsonSync(url, postdata){

 var jqxhr = $.ajax({
 type:"POST",
 url: url,
 data: postdata,
 dataType: 'json',
 cache: false,
 async: false
 });

//'async' has to be 'false' for this to work
 var response = {valid: jqxhr.statusText, data: jqxhr.responseJSON};

 return response;
}

请注意,上面的代码只适用的情况下异步 。 如果你设置 async:true 返回的对象 jqxhr不会有效的ajax调用返回时,后来异步调用完成时,但已为时太晚设置响应变量。

js客户端代码


function isValidLogin() {
 var flag = false;
 var Response = $.ajax({
 type:"POST",
 dataType:"json",
 contentType:"application/json; charset=utf-8",
 url:"UPSLabelFormCA.aspx/IsValidLogin",
 async: false
 }).responseText;

 var toJson = jQuery.parseJSON(Response);
 if (toJson.d[0].Message == 'SUCCESS') {
 flag = true;
 }
 return flag;
}

asp.net 服务器端代码


[WebMethod]
 public static List<ShipInfo> IsValidLogin()
 {
 List<ShipInfo> loginStatus = new List<ShipInfo>();
 if (HttpContext.Current.User.Identity.IsAuthenticated && HttpContext.Current.Session["Email"]!= null)
 {
 loginStatus.Add(new ShipInfo() { Success = true, Message ="SUCCESS" });
 }
 else
 {

 loginStatus.Add(new ShipInfo() { Success = false, Message ="FAILED" });
 }
 return loginStatus;

 }

...