2013-06-27 2 views
1

그래서 이것은 내 설정입니다. 여러 요소에서 .each를 호출하고 몇 가지 검사를 한 후 일부 JSON 데이터와 함께 아약스 요청을 보내고 성공하면 특성으로 서버 응답을 적용합니다 각 요소 (보통 id 임)에. 그 후 ID를 배열로 푸시합니다.여러 개의 각 및 아약스 요청

문제는 분명히 ajax 요청은 비동기 적이며 모든 Ajax가 완료되기 전에 요소 ID 배열을 사용하는 함수가 실행된다는 것입니다.

나는 .when과 .then를 시도했지만 콜백 함수가 계속 ajax보다 먼저 해고된다. 여기

(나는 불필요한 부분을 제거 한) 내 코드는 모습입니다 :

var order = []; 

function sub(selector){ 

selector.each(function(){ 
    var out = { 
     "some":"random", 
     "stuff":"here" 
    }; 
     $.ajax({ 
      type: "POST" 
      url: "/test/url", 
      dataType: 'json', 
      contentType: "application/json; charset=utf-8", 
      data:JSON.stringify(out), 
      success:function(response){ 
       $(this).attr("data-response",response); 
       order.push(response); 
      } 
     }) 
    }) 
} 

$("#button").click(function(){ 
    $.when(sub($(".test"))).then(function() { 
     console.log(order); 
     //i have to run the sub function twice so the order doesn't return undefined 
    });  
}); 
+0

당신이 순서 배열에 항목을 이용하여 수를 계속 확인 할 수 있습니다. setInterval을 사용하여 – bitkot

답변

1

문제는 연기 객체에 when 행위는, 그러나 하위 그렇게 when 화재 바로 아무것도 반환하지 않습니다. 직접 when는 물체의 배열을 허용하지 않는다는 것입니다 whenapply를 사용하는

var order = []; 

function sub(selector){ 
    var deferredList = [] 
    selector.each(function(){ 
     var out = { 
      "some":"random", 
      "stuff":"here" 
     }; 
     var deferred = $.ajax({ 
       type: "POST", 
       url: "/test/url", 
       dataType: 'json', 
       contentType: "application/json; charset=utf-8", 
       data:JSON.stringify(out), 
       success:function(response){ 
        $(this).attr("data-response",response); 
        order.push(response); 
       } 
      }) 
     deferredList.push(deferred) 
    }) 
    return deferredList; 
} 

$("#button").click(function(){ 
    $.when.apply($,sub($(".test"))).then(function() { 
     console.log(order); 
     //i have to run the sub function twice so the order doesn't return undefined 
    });  
}); 

이유를하지 : 그래서 당신이해야 할 것은 아약스 호출에 의해 반환 된 모든 지연된 개체를 수집하고이를 반환하는 것입니다 매개 변수이고 apply은이 문제에 대한 해결 방법을 제공합니다.

+0

이것은 모든 아약스 (순서 배열의 모든 값은 정의되지 않음)보다 먼저 발생합니다. –

+0

나를 위해 작동합니다. 코드의 문제가 다른 곳에서 발생했을 수 있습니다. –

+0

예, 실제로 좋았습니다. –

0

$.when()의 인수는 Deferred이어야하지만 sub()은 아무 것도 반환하지 않습니다. 이 버전은 이 반환 한 배열을 모두 $.ajax으로 반환하고, 모두 인수로 $.when을 호출합니다. 그러면 모든 것을 기다릴 것입니다.

var order = []; 

function sub(selector){ 
    return selector.map(function(){ 
     var out = { 
      "some":"random", 
      "stuff":"here" 
     }; 
     return $.ajax({ 
      type: "POST" 
      url: "/test/url", 
      dataType: 'json', 
      contentType: "application/json; charset=utf-8", 
      data:JSON.stringify(out), 
      success:function(response){ 
       $(this).attr("data-response",response); 
       order.push(response); 
      } 
     }) 
    }) 
} 

$("#button").click(function(){ 
    $.when.apply(this, sub($(".test"))).then(function() { 
     console.log(order); 
     //i have to run the sub function twice so the order doesn't return undefined 
    });  
}); 
+0

은'success'가 아닌'$ .ajax'에 의해 주어지는 반환 된 객체의 메소드일까요? – Alp

+1

'$ .ajax()'는'.done()'과 같은 AJAX 관련 메소드에'Promise' 인터페이스를 구현 한'jqXHR' 객체를 반환합니다. – Barmar

+0

나는 그것을 시도했지만 여전히 모든 아약스가 끝나기 전에 발화한다. –

-2

$ .ajax - call에 속성 async : false를 추가하십시오. 그런 다음 서로가 차례로 호출됩니다.

+0

이것은 좋은 해결책이 아니다. 비동기 호출을 사용하는 매우 좋은 이유가있다. –

+0

을 사용하면 작업 속도가 느려집니다. – Alp

+0

예. 속도가 느려집니다. 방금 질문에 답하면 제대로 작동합니다. 성능이 문제인 경우 OP는 각 함수 호출마다 하나의 서버 요청 만 수행되도록 코드를 다시 작성해야합니다 (가능한 경우) – bestprogrammerintheworld

0

귀하의 접근 방식은 훨씬 더 많은 서버 요청을 생성하며 대폭 확장 될 것입니다. 어쨌든 모든 결과를 기다리고 싶다면 훨씬 더 나은 해결책은 모든 데이터를 수집하고 각 데이터 객체에 대한 결과 배열을 반환하는 하나의 아약스 요청 만 보내는 것입니다.

지연된 개체를 사용하면 (다른 답변 에서처럼) when 문에 그 결과를 사용할 수 있습니다.

0

성공에 콜백 기능을 사용하려고 : 그것은 selector.each의로 같은 크기이다 전까지

var order = []; 

function sub(selector, callback){ 

selector.each(function(){ 
    var out = { 
     "some":"random", 
     "stuff":"here" 
    }; 
     $.ajax({ 
      type: "POST" 
      url: "/test/url", 
      dataType: 'json', 
      contentType: "application/json; charset=utf-8", 
      data:JSON.stringify(out), 
      success:function(response){ 
       $(this).attr("data-response",response); 
       order.push(response); 
       callback(); 
      } 
     }) 
    }) 
} 

$("#button").click(function(){ 
    sub($(".test"), function() { console.log(order) }); 
});