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

StackOverflow https://stackoverflow.com/questions/133310

문제

표준 확장 지점을 제공하는 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 문서: 당신은 그것을 지정합니다 비동기 옵션 거짓 동기식 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
    });
}

다른 팁

전화하여 jQuery의 Ajax 설정을 동기 모드로 넣을 수 있습니다.

jQuery.ajaxSetup({async:false});

그런 다음 Ajax 통화를 사용하여 수행하십시오 jQuery.get( ... );

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

jQuery.ajaxSetup({async:true});

@adam의 제안과 똑같은 일을하지만, 재구성하고 싶은 사람에게 도움이 될 수 있습니다. jQuery.get() 또는 jQuery.post() 더 정교한 사람에게 jQuery.ajax() 통사론.

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

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

이 모든 대답은 Async와 함께 Ajax 호출을 수행하면 Ajax 요청이 완료 될 때까지 브라우저가 매달릴 것입니다. Flow Control 라이브러리를 사용하면 브라우저를 끊지 않고이 문제를 해결합니다. 다음은 다음과 같은 예입니다 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();
}
function getURL(url){
    return $.ajax({
        type: "GET",
        url: url,
        cache: false,
        async: false
    }).responseText;
}


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

크로스 도메인 Ajax 전화를하는 경우 (사용하여 JSONP) - 너 캔트 동기식으로, async 깃발은 jQuery에 의해 무시됩니다.

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

JSONP-CALL의 경우 사용할 수 있습니다.

  1. 자신의 도메인에 대한 AJAX-CALL- 크로스 도메인 호출 서버 쪽을 수행하십시오.
  2. 비동기 적으로 작동하도록 코드를 변경하십시오
  3. Frame.js와 같은 "기능 시퀀서"라이브러리를 사용하십시오. 대답)
  4. 실행을 차단하는 대신 UI를 차단합니다 (이것은 대답) (내가 가장 좋아하는 방법)

참고 : 사용해서는 안됩니다 async: false 이 경고 메시지로 인해 :

Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / Seamonkey 2.27)으로 시작하여 메인 스레드의 동기 요청은 사용자 경험의 부정적인 영향으로 인해 더 이상 사용되지 않았습니다.

크롬은 심지어 콘솔에서 이것에 대해 경고합니다.

기본 스레드의 동기식 XMLHTTPREQUEST는 최종 사용자의 경험에 해로운 영향을 미치기 때문에 더 이상 사용되지 않습니다. 더 많은 도움을 받으려면 확인하십시오 https://xhr.spec.whatwg.org/.

이렇게하면 어느 날 작동을 멈출 수 있기 때문에 이와 같은 일을하고 있다면 페이지를 끊을 수 있습니다.

동기식이지만 여전히 차단하지 않는 경우에도 여전히 느끼는 방식을 원한다면 Async/Await을 사용해야하며 아마도 새로운 약속을 기반으로하는 일부 Ajax를 사용해야합니다. 술책 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의 허용 속성으로 동기화를 비활성화 할 수도 있습니다.

와 함께 async: false 당신은 차단 된 브라우저를 얻습니다. 비 차단 동기식 솔루션의 경우 다음을 사용할 수 있습니다.

ES6/ECMAScript2015

ES6을 사용하면 생성기 및 the를 사용할 수 있습니다 공동 도서관:

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

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' 그리고 .RESPONSETEXT 에게 ResponseJson.

나는 또한 그것을 사용하여 상태를 검색했습니다 statustext 반환 된 객체의 속성. 이것은 JSON이 유효한지 여부가 아니라 Ajax 응답의 상태입니다.

백엔드는 응답을 올바른 (잘 형성된) JSON으로 반환해야합니다. 그렇지 않으면 반환 된 객체가 정의되지 않습니다.

원래 질문에 대답 할 때 고려해야 할 두 가지 측면이 있습니다. 하나는 Ajax에게 동기식으로 수행하도록 지시하고 있습니다 (설정하여 비동기 : 거짓) 그리고 다른 하나는 콜백 함수가 아닌 호출 함수의 반환 문을 통해 응답을 반환합니다.

나는 또한 포스트와 함께 그것을 시도했고 그것은 효과가 있었다.

게시물을 게시하고 추가했습니다 데이터 : 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;
}

위의 코드는 경우에만 작동합니다. 비동기 ~이다 거짓. 당신이 설정했다면 비동기 : 참 반환 된 개체 JQXHR Ajax 통화가 반환 될 때 유효하지 않을 것입니다. 나중에 비동기 호출이 완료되었을 때만 나중에 응답 변하기 쉬운.

이것은 예입니다 :

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

첫째, 우리는 $ .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
    });

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

왜냐하면 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;
};

이것은 나의 "”네임 스페이스 :

var Thread = {
    sleep: function(ms) {
        var start = Date.now();

        while (true) {
            var clock = (Date.now() - start);
            if (clock >= ms) break;
        }

    }
};

그리고 이것이 내가 그것을 부르는 방법입니다.

var d1 = new Date();
console.log('start ' + d1.toLocaleTimeString());
Thread.sleep(10000);
var d2 = new Date();
console.log('end ' + d2.toLocaleTimeString());

콘솔을 보면 다음과 같은 결과를 얻을 수 있습니다.

start 1:41:21 PM
end 1:41:31 PM
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top