Як я магу атрымаць jQuery для выканання сінхроннага, а не асінхроннага запыту Ajax?

У мяне ёсць віджэт JavaScript, які падае стандартныя пункту пашырэння. Адна з іх - гэта функцыя beforecreate . Ён павінен вяртаць false каб прадухіліць стварэнне элемента.

Я дадаў выклік Ajax у гэтую функцыю, выкарыстоўваючы jQuery:

 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, а не ў адваротным выкліку. Ці ёсць спосаб выканаць сінхронны запыт AJAX з выкарыстаннем jQuery або любога іншага API-інтэрфейсу ў браўзэры?

1079
25 сент. зададзены Artem Tikhomirov 25 сент. 2008-09-25 16:26 '08 у 16:26 2008-09-25 16:26
@ 14 адказаў

З дакументацыі jQuery : вы паказваеце опцыю асінхронная як 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 }); } 
1053
25 сент. адказ дадзены Adam Bellaire 25 сент. 2008-09-25 16:30 '08 а 16:30 2008-09-25 16:30

Вы можаце ўсталяваць jQuery Ajax ў сінхронным рэжыме, патэлефанаваўшы

 jQuery.ajaxSetup({async:false}); 

Затым выканаеце вашы выклікі Ajax з дапамогай jQuery.get(... );

border=0

Затым проста ўключайце яго зноў

 jQuery.ajaxSetup({async:true}); 

Я мяркую, што гэта працуе так жа, як прапанавана @Adam, але можа быць карысна каму-то, хто хоча пераналадзіць свае jQuery.get() або jQuery.post() у больш складаны сінтаксіс jQuery.ajax() .

239
13 апр. адказ дадзены Sydwell 13 крас. 2011-04-13 00:45 '11 ў 0:45 2011-04-13 00:45

Выдатнае рашэнне! Я заўважыў, што калі я паспрабаваў рэалізаваць яго, калі б я вярнуў значэнне ў прапанова 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; } 
128
07 апр. адказ дадзены James in Indy 07 крас. 2010-04-07 16:30 '10 а 16:30 2010-04-07 16:30

Усе гэтыя адказы не згодныя з тым, што выкананне 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(); } 
82
28 апр. адказ дадзены BishopZ 28 крас. 2012-04-28 20:41 '12 а 20:41 2012-04-28 20:41
 function getURL(url){ return $.ajax({ type: "GET", url: url, cache: false, async: false }).responseText; } //example use var msg=getURL("message.php"); alert(msg); 
49
25 апр. адказ дадзены Carcione 25 крас. 2012-04-25 18:34 '12 у 18:34 2012-04-25 18:34

Майце на ўвазе, што калі вы выконваеце междоменный выклік Ajax (выкарыстоўваючы JSONP ) - вы не можаце рабіць ён сінхронна, сцяг async будзе ігнаравацца jQuery.

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

Для JSONP-выклікаў вы можаце выкарыстаць:

  • Ajax-выклік у ваш уласны дамен - і выканайце междоменный выклік на боку сервера
  • Зменіце свой код для працы асінхронна
  • Выкарыстоўвайце бібліятэку "секвенсер функцый", такую як Frame.js (гэты адказ )
  • Заблакуйце карыстацкі інтэрфейс замест блакавання выканання (гэты адказ ) (мой любімы спосаб)
22
10 мая '15 в 9:28 2015-05-10 09:28 адказ дадзены Serge Shultz 10 мая '15 у 09:28 2015/05/10 09:28

Заўвага. Вы не павінны выкарыстоўваць async з-за гэтага:

Пачынаючы з Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), сінхронныя запыты ў асноўным струмені састарэлі з-за негатыўных наступстваў для карыстальніка.

Chrome нават папярэджвае пра гэта ў кансолі:

Сінхронны XMLHttpRequest ў асноўным струмені састарэў з-за яго згубных наступстваў для канчатковага карыстальніка. Для атрымання дадатковай даведкі праверце https://xhr.spec.whatwg.org/ .

Гэта можа зламаць вашу старонку, калі вы робіце нешта падобнае, так як яна можа перастаць працаваць у любы дзень.

Калі вы хочаце зрабіць гэта так, як быццам гэта сінхронна, але ўсё роўна не блакаваць, вы павінны выкарыстоўваць async / wait і, магчыма, таксама ajax, заснаваны на абяцаннях, такіх як новы API Fetch

 async function foo() { var res = await fetch(url) console.log(res.ok) var json = await res.json() console.log(json) } 
19
13 дек. адказ дадзены Endless 13 снеж. 2016-12-13 15:55 '16 у 15:55 2016/12/13 15:55

Я выкарыстаў адказ, дадзены 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'); } } 

Я дадаў dataType 'JSON' і змяніў .responseText на responseJSON.

Я таксама атрымаў статус з выкарыстаннем ўласцівасці statusText якое вяртаецца аб'екта. Звярніце ўвагу, што гэта статус адказу Ajax, а не сапраўдны Ці JSON.

Ўнутраны сервер павінен вярнуць адказ у правільным (правільна сфармаваным) JSON, інакш які вяртаецца аб'ект будзе нявызначаным.

Пры адказе на зыходны пытанне неабходна ўлічваць два аспекты. Адзін кажа Ajax выконваць сінхронна (шляхам ўстаноўкі async: false), а другі вяртае адказ праз аператар вяртання функцыі выкліку, а не ў функцыю зваротнага выкліку.

Я таксама спрабаваў яго з дапамогай POST, і ён працаваў.

Я змяніў GET на POST і дадаў дадзеныя: 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 з'яўляецца ілжывым. Калі вы павінны былі ўсталяваць async: true, які вяртаецца аб'ект jqxhr ня дзейнічае падчас выкліку AJAX, толькі пазней, калі асінхронны выклік будзе завершаны, але занадта позна ўсталяваць зменную адказу.

10
15 нояб. адказ дадзены paulo62 15 лістапада. 2014-11-15 14:33 '14 У 14:33 2014/11/15 14:33

З 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 wait:

 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 })(); } 
9
20 авг. адказ дадзены Spen 20 жнів. 2016-08-20 22:52 '16 а 22:52 2016/08/20 22:52

Гэта прыклад:

 $.ajax({ url: "test.html", async: false }).done(function(data) { // Todo something.. }).fail(function(xhr) { // Todo something.. }); 
6
16 авг. адказ дадзены searching9x 16 жнів. 2014-08-16 16:20 '14 у 16:20 2014/08/16 16:20

Кліенцкі код JavaScript на JavaScript

 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; } 
5
02 дек. адказ дадзены Thomas 02 снеж. 2014-12-02 16:02 '14 у 16:02 2014/12/02 16:02

Па-першае, мы павінны разумець, калі мы выкарыстоўваем $ .ajax і калі мы выкарыстоўваем $ .get / $. post

Калі мы патрабуем нізкага ўзроўню кантролю над запытам ajax, такім як налады загалоўка запыту, налады кэшавання, сінхронныя налады і г.д., тады мы павінны пайсці на $ .ajax.

$. get / $. post: Калі мы не патрабуем нізкага ўзроўню кантролю над ajax-запытам. Проста проста атрымлівайце / адпраўляйце дадзеныя на сервер. гэта скарачэнне

 $.ajax({ url: url, data: data, success: success, dataType: dataType }); 

і, такім чынам, мы не можам выкарыстоўваць іншыя функцыі (сінхранізацыя, кэш і г.д.) з дапамогай $ .get / $. post.

Такім чынам, для кіравання нізкім узроўнем (сінхранізацыя, кэш і г.д.) па запыту ajax мы павінны перайсці на $ .ajax

  $.ajax({ type: 'GET', url: url, data: data, success: success, dataType: dataType, async:false }); 
2
03 окт. адказ дадзены Sheo Dayal Singh 03 каст. 2017-10-03 12:52 '17 у 12:52 2017/10/03 00:52

гэта мая простая рэалізацыя для запытаў ASYNC з дапамогай jQuery. Спадзяюся, гэта дапаможа каму заўгодна.

 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(); 
0
15 февр. адказ дадзены Felipe Marques 15 февр. 2018-02-15 22:55 '18 а 22:55 2018/02/15 22:55

Паколькі сінхронная аперацыя XMLHttpReponse састарэла, я прыдумаў наступнае рашэнне, якое абгортваюць XMLHttpRequest . Гэта дазваляе заказваць запыты AJAX, захоўваючы пры гэтым асінхронны характар, што вельмі карысна для аднаразовых токенаў CSRF.

Ён таксама празрысты, таму бібліятэкі, такія як jQuery, будуць працаваць без збояў.

  var XHRQueue = []; var _XMLHttpRequest = XMLHttpRequest; XMLHttpRequest = function() { var xhr = new _XMLHttpRequest(); var _send = xhr.send; xhr.send = function() {  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];   _send.apply(xhr, args); }; xhr.addEventListener('load', function(e) {   XHRQueue.shift(); if (XHRQueue.length) this.processQueue(); }); return xhr; }; here  var XHRQueue = []; var _XMLHttpRequest = XMLHttpRequest; XMLHttpRequest = function() { var xhr = new _XMLHttpRequest(); var _send = xhr.send; xhr.send = function() {  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];   _send.apply(xhr, args); }; xhr.addEventListener('load', function(e) {   XHRQueue.shift(); if (XHRQueue.length) this.processQueue(); }); return xhr; }; here  var XHRQueue = []; var _XMLHttpRequest = XMLHttpRequest; XMLHttpRequest = function() { var xhr = new _XMLHttpRequest(); var _send = xhr.send; xhr.send = function() {  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];   _send.apply(xhr, args); }; xhr.addEventListener('load', function(e) {   XHRQueue.shift(); if (XHRQueue.length) this.processQueue(); }); return xhr; }; more  var XHRQueue = []; var _XMLHttpRequest = XMLHttpRequest; XMLHttpRequest = function() { var xhr = new _XMLHttpRequest(); var _send = xhr.send; xhr.send = function() {  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];   _send.apply(xhr, args); }; xhr.addEventListener('load', function(e) {   XHRQueue.shift(); if (XHRQueue.length) this.processQueue(); }); return xhr; }; 
0
29 апр. адказ дадзены Geoffrey 29 крас. 2018-04-29 13:50 '18 у 13:50 2018/04/29 13:50

Іншыя пытанні па пазнаках або Задайце пытанне