질문자 :Artem Tikhomirov
표준 확장점을 제공하는 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 요청을 수행하는 방법이 있습니까?
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 }); }
Adam Bellaire다음을 호출하여 jQuery의 Ajax 설정을 동기 모드로 설정할 수 있습니다.
jQuery.ajaxSetup({async:false});
jQuery.get( ... );
사용하여 Ajax 호출을 수행합니다.
그런 다음 다시 한 번 켜십시오.
jQuery.ajaxSetup({async:true});
@Adam이 제안한 것과 동일한 방식으로 작동한다고 생각하지만 jQuery.get()
또는 jQuery.post()
를 보다 정교한 jQuery.ajax()
구문으로 재구성하려는 사람에게 도움이 될 수 있습니다.
Sydwell탁월한 솔루션! 나는 그것을 구현하려고 할 때 성공 절에서 값을 반환하면 정의되지 않은 것으로 돌아오는 것을 알아차렸습니다. 변수에 저장하고 해당 변수를 반환해야 했습니다. 이것은 내가 생각해 낸 방법입니다.
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; }
James in Indy이러한 모든 답변은 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(); }
BishopZfunction getURL(url){ return $.ajax({ type: "GET", url: url, cache: false, async: false }).responseText; } //example use var msg=getURL("message.php"); alert(msg);
Carcione참고: async: false
를 사용하면 안 됩니다.
Gecko 30.0(Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27)부터 메인 스레드의 동기 요청은 사용자 경험에 대한 부정적인 영향으로 인해 더 이상 사용되지 않습니다.
Chrome은 콘솔에서 이에 대해 경고하기도 합니다.
메인 스레드의 동기 XMLHttpRequest는 최종 사용자의 경험에 해로운 영향을 미치기 때문에 더 이상 사용되지 않습니다. 추가 도움이 필요하면 https://xhr.spec.whatwg.org/를 확인하세요.
언젠가 작동이 중지될 수 있으므로 이와 같은 작업을 수행하는 경우 페이지가 손상될 수 있습니다.
동기식이지만 여전히 차단되지 않는 것처럼 느껴지는 방식으로 수행하려면 async/await를 사용해야 하며 새로운 Fetch API와 같은 약속을 기반으로 하는 일부 ajax도 사용해야 합니다.
async function foo() { var res = await fetch(url) console.log(res.ok) var json = await res.json() console.log(json) }
편집 크롬은 사용자가 페이지를 탐색하거나 닫을 때 페이지 해제 시 동기화 XHR 허용 안 함에서 작동합니다. 여기에는 beforeunload, unload, pagehide 및 visibilitychange가 포함됩니다.
이것이 사용 사례라면 대신 navigator.sendBeacon을 살펴보고 싶을 수 있습니다.
페이지에서 http 헤더 또는 iframe의 허용 속성을 사용하여 동기화 요청을 비활성화할 수도 있습니다.
Endless교차 도메인 Ajax 호출( JSONP 사용)을 수행하는 경우 동기적으로 수행 할 수 없으며 async
플래그를 무시합니다.
$.ajax({ url: "testserver.php", dataType: 'jsonp', // jsonp async: false //IGNORED!! });
JSONP 호출의 경우 다음을 사용할 수 있습니다.
- 자신의 도메인에 대한 Ajax 호출 - 서버 측에서 도메인 간 호출 수행
- 비동기식으로 작동하도록 코드 변경
- Frame.js와 같은 "함수 시퀀서" 라이브러리 사용(이 답변 )
- 실행을 차단하는 대신 UI 차단(이 답변 )(내가 가장 좋아하는 방법)
Serge ShultzCarcione에서 제공한 답변을 사용하고 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' 의 dataType 을 추가하고 .responseText 를 responseJSON으로 변경했습니다.
또한 반환된 객체 의 statusText 속성을 사용하여 상태를 검색했습니다. 이것은 JSON이 유효한지 여부가 아니라 Ajax 응답의 상태입니다.
백엔드는 올바른(정형화된) JSON으로 응답을 반환해야 합니다. 그렇지 않으면 반환된 객체가 정의되지 않습니다.
원래 질문에 답할 때 고려해야 할 두 가지 측면이 있습니다. 하나는 Ajax에게 동기적으로 수행하도록 지시하고( async: false 를 설정하여) 다른 하나는 콜백 함수가 아닌 호출 함수의 return 문을 통해 응답을 반환합니다.
나는 또한 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 가 false 인 경우에만 작동합니다. async: true 를 설정했다면 반환된 객체 jqxhr 은 AJAX 호출이 반환될 때 유효하지 않고 나중에 비동기 호출이 완료되었을 때만 유효하지만 응답 변수를 설정하기에는 너무 늦었습니다.
paulo62async: false
를 사용하면 차단된 브라우저가 나타납니다. 비차단 동기 솔루션의 경우 다음을 사용할 수 있습니다.
ES6/ECMAScript2015
ES6에서는 생성기 및 공동 라이브러리를 사용할 수 있습니다.
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 await를 사용할 수 있습니다.
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 })(); }
Spenhouet다음은 예입니다.
$.ajax({ url: "test.html", async: false }).done(function(data) { // Todo something.. }).fail(function(xhr) { // Todo something.. });
searching9x먼저 $.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 });
Sheo Dayal Singh이것은 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();
Felipe Marques때문에 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; };
Geoffrey원래의 질문에 대해 이었기 때문에 jQuery.get
, 그것은 (언급 한 것을 여기에서 언급 할 가치가 여기에 ) 하나를 사용할 수 async: false
A의 $.get()
비동기 이래로 이상적으로 그것을 피하기는 XMLHTTPRequest
되지 않습니다 (그리고 브라우저가를 제공 할 수 있습니다 경고):
$.get({ url: url,// mandatory data: data, success: success, dataType: dataType, async:false // to make it synchronous });
Anupam출처 : http:www.stackoverflow.com/questions/133310/how-can-i-get-jquery-to-perform-a-synchronous-rather-than-asynchronous-ajax-re