java ajax同步请求,如何让jQuery执行同步而非异步的Ajax请求?

回答(13)

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

function getURL(url){

return $.ajax({

type: "GET",

url: url,

cache: false,

async: false

}).responseText;

}

//example use

var msg=getURL("message.php");

alert(msg);

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

所有这些答案都错过了使用async:false进行Ajax调用将导致浏览器挂起直到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();

}

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

从jQuery documentation:您指定 asynchronous 选项为 false 以获取同步Ajax请求 . 然后你的回调可以在你的母亲功能进行之前设置一些数据 .

如果按照建议更改,您的代码将如下所示:

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

});

}

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

优秀解决方案我注意到当我尝试实现它时,如果我在success子句中返回了一个值,那么它将返回undefined . 我必须将它存储在变量中并返回该变量 . 这是我提出的方法:

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;

}

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

我使用了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' 的 'JSON' 并将 .responseText 更改为 responseJSON .

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

后端必须以正确(格式良好)的JSON返回响应,否则返回的对象将是未定义的 .

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

我也尝试过POST,但它确实有效 .

我将GET更改为POST并添加了 data: 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 为 false 的情况 . 如果要设置 async: true ,则返回的对象 jqxhr 在AJAX调用返回时无效,仅在异步调用结束后才有效,但设置 response 变量为时已晚 .

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

这是一个例子:

$.ajax({

url: "test.html",

async: false

}).done(function(data) {

// Todo something..

}).fail(function(xhr) {

// Todo something..

});

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

Firstly we should understand when we use $.ajax and when we use $.get/$.post

当我们需要对ajax请求进行低级别控制时,例如请求标头设置,缓存设置,同步设置等,然后我们应该去$ .ajax .

$ .get / $ .post:当我们不需要对ajax请求进行低级别控制时 . 只需将数据获取/发布到服务器 . It is shorthand of

$.ajax({

url: url,

data: data,

success: success,

dataType: dataType

});

因此我们不能使用$ .get / $ .post的其他功能(同步,缓存等) .

Hence for low level control(sync,cache,etc.) over ajax request,we should go for $.ajax

$.ajax({

type: 'GET',

url: url,

data: data,

success: success,

dataType: dataType,

async:false

});

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

因为不推荐使用 XMLHttpReponse 同步操作,所以我提出了以下包装 XMLHttpRequest 的解决方案 . 这允许有序的AJAX查询,同时仍然是异常的,这对于单次使用CSRF令牌非常有用 .

它也是透明的,因此诸如jQuery之类的库将无缝运行 .

/* wrap XMLHttpRequest for synchronous operation */

var XHRQueue = [];

var _XMLHttpRequest = XMLHttpRequest;

XMLHttpRequest = function()

{

var xhr = new _XMLHttpRequest();

var _send = xhr.send;

xhr.send = function()

{

/* queue the request, and if it's the first, process it */

XHRQueue.push([this, arguments]);

if (XHRQueue.length == 1)

this.processQueue();

};

xhr.processQueue = function()

{

var call = XHRQueue[0];

var xhr = call[0];

var args = call[1];

/* you could also set a CSRF token header here */

/* send the request */

_send.apply(xhr, args);

};

xhr.addEventListener('load', function(e)

{

/* you could also retrieve a CSRF token header here */

/* remove the completed request and if there is more, trigger the next */

XHRQueue.shift();

if (XHRQueue.length)

this.processQueue();

});

return xhr;

};

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

您可以通过调用将jQuery的Ajax设置置于同步模式

jQuery.ajaxSetup({async:false});

然后使用 jQuery.get( ... ); 执行Ajax调用

然后再打开一次

jQuery.ajaxSetup({async:true});

我想这与@Adam所建议的相同,但对于那些想要将 jQuery.get() 或 jQuery.post() 重新配置为更复杂的 jQuery.ajax() 语法的人来说,它可能会有所帮助 .

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

请记住,如果您正在进行跨域Ajax调用(通过使用JSONP) - 您 can't 同步执行,jQuery将忽略 async 标志 .

$.ajax({

url: "testserver.php",

dataType: 'jsonp', // jsonp

async: false //IGNORED!!

});

对于JSONP调用,您可以使用:

Ajax-调用您自己的域 - 并进行跨域调用服务器端

将代码更改为异步工作

使用像Frame.js这样的"function sequencer"库(这个answer)

阻止UI而不是阻止执行(这是answer)(我最喜欢的方式)

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

这是我使用jQuery对ASYNC请求的简单实现 . 我希望这有助于任何人 .

var queueUrlsForRemove = [

'http://dev-myurl.com/image/1',

'http://dev-myurl.com/image/2',

'http://dev-myurl.com/image/3',

];

var queueImagesDelete = function(){

deleteImage( queueUrlsForRemove.splice(0,1), function(){

if (queueUrlsForRemove.length > 0) {

queueImagesDelete();

}

});

}

var deleteImage = function(url, callback) {

$.ajax({

url: url,

method: 'DELETE'

}).done(function(response){

typeof(callback) == 'function' ? callback(response) : null;

});

}

queueImagesDelete();

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

使用 async: false ,您将获得一个被阻止的浏览器 . 对于非阻塞同步解决方案,您可以使用以下内容:

ES6 / ECMAScript2015

使用ES6,您可以使用生成器和co library:

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

co(function*(){

let result = yield jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value));

//Just use the result here

});

}

ES7

使用ES7,您可以使用asyc等待:

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

(async function(){

let result = await jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value));

//Just use the result here

})();

}

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

注意:由于这个原因,您不应该使用async:

从Gecko 30.0(Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27)开始,由于对用户体验的负面影响,主线程上的同步请求已被弃用 .

Chrome甚至在控制台中发出警告:

主线程上的同步XMLHttpRequest因其对最终用户体验的不利影响而被弃用 . 如需更多帮助,请查看https://xhr.spec.whatwg.org/ .

如果您正在做这样的事情,这可能会破坏您的页面,因为它可能会在任何一天停止工作 .

如果你想这样做仍然感觉像是阻塞那么你应该使用async / await,也许还有一些基于promises的ajax,比如新的Fetch API

async function foo() {

var res = await fetch(url)

console.log(res.ok)

var json = await res.json()

console.log(json)

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值