2013-02-22 2 views
12

실행하려고하는 세 가지 함수가 있습니다. 첫 번째 두 함수는 세 번째 함수에 대한 데이터가 필요한 비동기식 작업을 수행하고 있습니다. 1과 2가 모두 완료 될 때만 세 번째 함수가 실행되기를 원합니다. 이것은 일반적인 구조이지만 1과 2가 끝나기 전에 마지막 함수가 실행됩니다. return d.promise(); :jquery 사용자 정의 지연 함수

function run() { 
    var data1 = {}; 
    var data2 = {}; 

    $.when(first(), second()).done(constructData()); 

    function first() { 
     var d = new $.Deferred(); 

     //do a bunch of stuff async 
     data1 = {}; 

     d.resolve(); 
    } 
    function second() { 


     var d = new $.Deferred(); 

     //do a bunch of stuff async 
     data2 = {}; 
     d.resolve(); 
    } 
    function constructData() { 
     //do stuff with data1 and data2 
    } 

} 

답변 데이터 당신이 first()을해야하고 약속을 반환 second() 생각 즉시

$.when(first(), second()).done(constructData); 

답변

23

약속 객체를 반환해야합니다.

function run() { 
    var data1 = {}; 
    var data2 = {}; 

    $.when(first(), second()).done(constructData); 

    function first() { 
     return $.Deferred(function() { // <-- see returning Deferred object 
      var self = this; 

      setTimeout(function() { // <-- example of some async operation 
       data1 = {func: 'first', data: true}; 
       self.resolve();  // <-- call resolve method once async is done 
      }, 2000); 
     }); 
    } 
    function second() { 
     return $.Deferred(function() { 
      var self = this; 
      setTimeout(function() { 
       data2 = {func: 'second', data: true}; 
       self.resolve(); 
      }, 3000); 
     }); 
    } 
    function constructData() { 
     //do stuff with data1 and data2 
     console.log(data1, data2); 
    } 
} 

http://jsfiddle.net/FwXZC/

+0

은 구조 데이터를 호출하지 않고 바로 트릭을했습니다! – Brian

+0

와우, 지연된 객체 내부에이 함수를 쓸 수 있다는 것을 몰랐습니다. 감사합니다! – Denis

+0

@ 데니스 나는 그것을하는 적절한 방법이라고 생각하지 않습니다. jQuery [docs] (https://api.jquery.com/jquery.deferred/)에 따르면 : beforeStart' 매개 변수는 "생성자가 반환하기 바로 전에 호출되는 함수입니다."_. 그래서이 함수는 지연된 객체가 생성되기 전에 호출됩니다. –

1

를 구성 부르지했다. docs에서 : 하나의 인수가 jQuery.when에 전달되며, 그렇지 않은 경우

이연 또는이 이연 해결과 연결된 모든 doneCallbacks 즉시 실행됩니다 같은 약속이,이 처리됩니다.

이것이 when 전화가 constructData을 너무 빨리 호출하는 이유 일 수 있습니다.

비동기 작업이 완료된 후에는 코드를 알기가 어렵지만 d.resolve()을 호출해야합니다.

data2을 명시 적으로 설정하는보다 자연스러운 방법은 resolve이 호출 될 때 제공되는 데이터를 사용하는 것입니다. 이것은 당신의 when 호출은 다음과 같이 보일 것이라는 점을 의미 다음 done 방법에 공급되는 결과의 정확한 형식은 연기 객체의 특성에 따라 달라

$.when(first(), second()).done(function(result1, result2) { 
    data1 = result1[0]; 
    data2 = result2[0]; 

    constructData(); 
}); 

참고. 약속이 $.ajax로 전화를 통해 반환되면 결과는 [data, statusText, jqXhrObject] 형식이어야합니다.

+0

그래 나는 추가하지 않은 :

$.when(first(), second()).done(constructData()); 

는 그것이 될 수 있도록 모두 함께

$.when(first(), second()).done(constructData); // don't call constructData immediately 

해야한다 : 당신은 또한이 라인에서 오류가 모든 비동기 코드는 사용자 정의 비 jquery 아약스 요청을 한꺼번에 가져 왔으며 오류는 done 함수를 호출하는 방법이었습니다 – Brian