我有一个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
,而不是在回调中 . 有没有办法使用jQuery或任何其他浏览器中的API执行同步AJAX请求?
13 回答
所有这些答案都错过了使用async:false进行Ajax调用将导致浏览器挂起直到Ajax请求完成的问题 . 使用流量控制库将解决此问题,而无需挂起浏览器 . 以下是Frame.js的示例:
从jQuery documentation:您指定 asynchronous 选项为 false 以获取同步Ajax请求 . 然后你的回调可以在你的母亲功能进行之前设置一些数据 .
如果按照建议更改,您的代码将如下所示:
优秀解决方案我注意到当我尝试实现它时,如果我在success子句中返回了一个值,那么它将返回undefined . 我必须将它存储在变量中并返回该变量 . 这是我提出的方法:
我使用了Carcione给出的答案并将其修改为使用JSON .
我添加了 'JSON' 的 'JSON' 并将 .responseText 更改为 responseJSON .
我还使用返回对象的 statusText 属性检索状态 . 请注意,这是Ajax响应的状态,而不是JSON是否有效 .
后端必须以正确(格式良好)的JSON返回响应,否则返回的对象将是未定义的 .
回答原始问题时需要考虑两个方面 . 一个是告诉Ajax同步执行(通过设置 async: false ),另一个是通过调用函数的return语句返回响应,而不是回调函数 .
我也尝试过POST,但它确实有效 .
我将GET更改为POST并添加了 data: postdata
请注意,上述代码仅适用于 async 为 false 的情况 . 如果要设置 async: true ,则返回的对象 jqxhr 在AJAX调用返回时无效,仅在异步调用结束后才有效,但设置 response 变量为时已晚 .
这是一个例子:
Firstly we should understand when we use $.ajax and when we use $.get/$.post
当我们需要对ajax请求进行低级别控制时,例如请求标头设置,缓存设置,同步设置等,然后我们应该去$ .ajax .
$ .get / $ .post:当我们不需要对ajax请求进行低级别控制时 . 只需将数据获取/发布到服务器 . It is shorthand of
因此我们不能使用$ .get / $ .post的其他功能(同步,缓存等) .
Hence for low level control(sync,cache,etc.) over ajax request,we should go for $.ajax
因为不推荐使用
XMLHttpReponse
同步操作,所以我提出了以下包装XMLHttpRequest
的解决方案 . 这允许有序的AJAX查询,同时仍然是异常的,这对于单次使用CSRF令牌非常有用 .它也是透明的,因此诸如jQuery之类的库将无缝运行 .
您可以通过调用将jQuery的Ajax设置置于同步模式
然后使用
jQuery.get( ... );
执行Ajax调用然后再打开一次
我想这与@Adam所建议的相同,但对于那些想要将
jQuery.get()
或jQuery.post()
重新配置为更复杂的jQuery.ajax()
语法的人来说,它可能会有所帮助 .请记住,如果您正在进行跨域Ajax调用(通过使用JSONP) - 您 can't 同步执行,jQuery将忽略
async
标志 .对于JSONP调用,您可以使用:
Ajax-调用您自己的域 - 并进行跨域调用服务器端
将代码更改为异步工作
使用像Frame.js这样的"function sequencer"库(这个answer)
阻止UI而不是阻止执行(这是answer)(我最喜欢的方式)
这是我使用jQuery对ASYNC请求的简单实现 . 我希望这有助于任何人 .
使用
async: false
,您将获得一个被阻止的浏览器 . 对于非阻塞同步解决方案,您可以使用以下内容:ES6 / ECMAScript2015
使用ES6,您可以使用生成器和co library:
ES7
使用ES7,您可以使用asyc等待:
注意:由于这个原因,您不应该使用async:
Chrome甚至在控制台中发出警告:
如果您正在做这样的事情,这可能会破坏您的页面,因为它可能会在任何一天停止工作 .
如果你想这样做仍然感觉像是阻塞那么你应该使用async / await,也许还有一些基于promises的ajax,比如新的Fetch API