jQuery가 비동기 Ajax 요청이 아닌 동기식을 수행하도록하려면 어떻게해야합니까?


1207

표준 확장 점을 제공하는 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 요청을 수행하는 방법이 있습니까?


30
이를 해결하는 올바른 방법은 위젯의 확장 점 사용 약속을 다시 작성하는 것입니다. 이 방법을 사용하면 ajax 요청과 같은 비동기 작업을 다음과 같이 쉽게 설정할 수 있습니다 beforecreate.
코스

3
Sajak 기능을 제안합니다. 편지 T가 있습니까? 네, 바나, 3T주세요.
Cody O'Dell

2
@Kos가 자리를 잡았습니다. 동기화 XHR은 여기에 필요하지 않습니다
Michael Westcott

1
사람들이 자바 스크립트를 시작할 때 하나의 조언을 요구한다면, 나는 말합니다 : 자바 스크립트의 비동기 문자를 받아들이십시오.
Emmanuel Delay

3
이 질문은 "사용자 암호를 일반 텍스트로 저장하는 방법"과 같은 질문입니다. 물론 답이 있지만하지 마십시오.
Vectorjohn

답변:


1165

로부터 의 jQuery 문서 : 당신은 지정 비동기 로 옵션을 거짓 동기 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
    });
}

97
정확히는 동기 호출에 get (), post (), load ()를 사용할 수 없습니다. ajax ()에만 "async"매개 변수가 있으며 "false"로 설정할 수 있습니다.
SLA80

39
@ SLA80 아뇨. jQuery 1.1 이후 : stackoverflow.com/questions/6849686/…
StuperUser 2012 년

16
@qualidafial 내 의견은 SLA80의 잘못된 의견입니다. 동기 호출에 get (), post (), load ()를 사용할 수 있습니다.
StuperUser

9
jQuery> = 1.8에서는 async false가 더 이상 지원되지 않습니다.
ken

22
@ken async: false은 여전히 ​​jQuery> = 1.8에서 지원됩니다. async: falsejqXHR ( $.Deferred) 과 함께 사용하는 기능 은 더 이상 사용되지 않습니다. 다시 말해, 기존 방법 (예 :) 대신 새로운 성공 / 오류 / 완전한 콜백 옵션을 사용해야합니다 jqXHR.done().
벤 존슨

255

호출하여 jQuery의 Ajax 설정을 동기 모드로 설정할 수 있습니다

jQuery.ajaxSetup({async:false});

그런 다음 다음을 사용하여 Ajax 호출을 수행하십시오. jQuery.get( ... );

그런 다음 다시 한 번 켜십시오.

jQuery.ajaxSetup({async:true});

@Adam이 제안한 것과 똑같이 작동하지만, 재구성 jQuery.get()하거나 jQuery.post()더 정교한 jQuery.ajax()구문 을 원하는 사람에게는 도움이 될 수 있습니다 .


56
이것은 정말 나쁜 생각입니다. 왜 글로벌 수준으로 설정하겠습니까? 그리고 나서 설정을 해제해야합니까?
Juan Mendes

11
적어도 이것이 가장 나쁜 생각입니다. "여기에는 방법이 없습니다"라고 말하는 대신 $.ajax(). ;)
Rzassar

136

훌륭한 솔루션! 성공 조항에서 값을 반환하면 정의되지 않은 것으로 돌아온 것을 구현하려고 시도했습니다. 변수에 저장하고 해당 변수를 반환해야했습니다. 이것이 내가 생각해 낸 방법입니다.

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;
}

16
이는에서가 아닌 콜백에서 값을 반환했기 때문입니다 getWhatever. 따라서 당신은 반환 아무것도undefined당신에서 getWhatever.
궤도에서 가벼움 레이스

6
이것은 절대적으로 잘못입니다. 'strReturn'을 리턴 할 때 비동기 호출이 완료되었는지 확신 할 수 없습니다.
토마스 프리츠

61
이것은 동기 호출입니다 (async : false).
James in Indy

85

이 모든 대답은 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();
}

4
REST 백엔드에 대한 빠른 테스트 하네스를 구성하고 콜백 지옥보다 단순성을 선호하는 경우 동기 호출이 편리합니다.
Distortum

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


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

10
그러나 다음과 같은 결과를 얻을 수 있습니다. '주 스레드의 동기 XMLHttpRequest는 최종 사용자의 경험에 해로운 영향으로 인해 더 이상 사용되지 않습니다.'
Hari

5
@Hari 주 스레드를 사용하지 않고 jQuery를 사용하여 동기 ajax 호출을 수행하는 방법은 무엇입니까?
Jose Nobile

7
나는이 답변에 제공 할 것이 무엇인지 알지 못합니다. 허용 된 답변은 함수에 싸여 4 년 후에 대답했습니다. 함수가 수행하는 기능을 나타내지 않기 때문에 사람들에게 C + P에게 조언하는 것은 좋지 않습니다. "그래서 getURLget? 왜 하나는 브라우저를 걸어합니까?" 등
moopet

27

참고 : 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 와 같은 약속을 기반으로하는 일부 아약스를 사용해야 합니다

async function foo() {
  var res = await fetch(url)
  console.log(res.ok)
  var json = await res.json()
  console.log(json)
}

페이지 편집 에서 동기화 XHR 허용 안 함 에서 크롬 편집 중사용자가 페이지를 탐색하거나 닫을 때 . 언로드, 언로드, 페이지 숨기기 및 가시성 변경이 포함됩니다.

이것이 유스 케이스 인 경우 대신 navigator.sendBeacon을 보고 싶을 수도 있습니다

페이지가 http 헤더 또는 iframe의 allow 속성으로 sync req를 비활성화 할 수도 있습니다.


당신이 당신의 포장해야합니다 await fetch(url)A의 호출을 try... catch비동기 오류를 포착하기 위해 블록.
inostia

4
함수 foo는 async처음에 단어 를 사용함으로써 약속으로 변환 되었으므로, 당신 foo().catch(...)도 그것을 잡을 수 있습니다
Endless

크롬은 이미 페이지 내에서 비동기 아약스를 허용하지 beforeunload않았지만 부정적인 피드백 버그
Alex

26

교차 도메인 Ajax 호출을 수행하는 경우 ( JSONP 사용 ) 동 기적으로 수행 할 수 없으면async 플래그는 jQuery에 의해 무시됩니다.

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

JSONP 통화의 경우 다음을 사용할 수 있습니다.

  1. 자신의 도메인으로 Ajax 통화-도메인 간 통화 서버 측
  2. 비동기식으로 작동하도록 코드 변경
  3. Frame.js와 같은 "함수 시퀀서"라이브러리를 사용하십시오 (이 답변 )
  4. 실행을 차단하는 대신 UI를 차단하십시오 (이 답변 ) (내가 가장 좋아하는 방법)

12

async: 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
    })(); 
}

3
자체 호출 된 비동기 함수 async function를 작성 beforecreate: async function(....하고 제거 하기 전에 전달할 수 있습니다.
Daniel Krom

12

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'dataType 을 추가하고 .responseTextresponseJSON으로 변경했습니다. .

또한 반환 된 객체 의 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;
}

위의 코드 는 asyncfalse 인 경우에만 작동합니다 . async : true 로 설정 한 경우 , 반환 된 객체 jqxhr 은 AJAX 호출이 반환 될 때 유효하지 않습니다. 나중에 비동기 호출이 완료된 경우에만 응답 변수 를 설정하기에는 너무 늦습니다 .


7

이것은 예입니다 :

$.ajax({
  url: "test.html",
  async: false
}).done(function(data) {
   // Todo something..
}).fail(function(xhr)  {
   // Todo something..
});

1
async false약속 기반 솔루션과 함께 사용하는 요점은 무엇입니까? 이것은 전혀 이익을 위해 브라우저를 잠급니다.
사라 코딩

2
@GoneCoding 정확한 순서대로 코드를 실행하려는 상황이 있습니다.이 상황에서 우리는 async false를 사용할 수 있습니다
Nikki

1
@ Nikki : 그것은 순차적으로 실행하는 방법이 아닙니다 . 비동기 약속 ( ajax호출이 이미 반환 된) 및 .then()/ 또는 done()(이미 표시된대로)를 사용하십시오. 브라우저를 잠그는 것은 매우 열악한 사용자 경험입니다. 내가 말했듯 async: false이이 예제에서 갖는 것은 완전한 시간 낭비입니다.
Gone Coding 코딩

4

먼저 $ .ajax를 사용할 때와 $ .get / $. post를 사용할 때를 이해해야합니다.

요청 헤더 설정, 캐싱 설정, 동기 설정 등과 같은 아약스 요청에 대한 저수준 제어가 필요한 경우 $ .ajax로 이동해야합니다.

$ .get / $. post : ajax 요청에 대한 저수준 제어가 필요하지 않은 경우 서버로 데이터를 가져 오거나 게시하는 것만 가능합니다. 의 속기

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

따라서 $ .get / $. post와 함께 다른 기능 (동기화, 캐시 등)을 사용할 수 없습니다.

따라서 아약스 요청을 통한 저수준 제어 (동기화, 캐시 등)를 위해서는 $ .ajax 가야합니다.

 $.ajax({
     type: 'GET',
      url: url,
      data: data,
      success: success,
      dataType: dataType,
      async:false
    });

2

이것은 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();

2

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;
};

-1

원래의 질문에 대한 이었기 때문에 jQuery.get, 그것은 (언급 한 것을 여기에서 언급 할 가치가 여기에 ) 한 사용 async: falseA의 $.get()하지만 이상적으로 피 비동기 이후를 XMLHTTPRequest더 이상 사용되지 않습니다 (브라우저가 경고를 줄 수는)

$.get({
  url: url,// mandatory
  data: data,
  success: success,
  dataType: dataType,
  async:false // to make it synchronous
});

1
이것이 왜 다운 보트입니까?
alias51

-2

asyn:falseAjax 요청에서 동기화하도록 설정하십시오 .

코드 샘플은 다음과 같습니다.

 $.ajax({
    url: 'some_url',
    type: "GET",
    async: false,
    cache: false,
    dataType: "JSON",
    data: { 
      "p1": v1, 
      "p2": v2
    },
    success: function(result) {
    }  
  }
});

이로 인해 화면이 응답하지 않을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.