2016-10-29 1 views
2

많은 리소스를로드 한 다음 이러한 요청에서 데이터를 검색하여 DOM을 렌더링하는 것처럼 최종 콜백을 실행하면 리소스 로더가 필요합니다.최종 콜백, 신뢰할 수없는 주문이있는 많은 요청이 있습니까?

다음은 함수의 :

var ResourceLoader = function() { 

    this.requests = new Array(); 
    this.FinalCallback; 

    this.Add = function (request) { 
     this.requests.push(request); 
    }; 

    this.Execute = function() { 

     for (var x = 0; x < this.requests.length ; x++) { 

      var success = this.requests[x].success; 

      //if this is the last of the requests... 
      if (x == (this.requests.length - 1) && this.FinalCallback) { 

       $.when($.ajax({ 
          url: this.requests[x].url, 
          dataType: 'json', 
          error: this.requests[x].error, 
          method: 'GET' 
         }).done(success)).then(this.FinalCallback); 
      } 
      else { 

       $.ajax({ 
        url: this.requests[x].url, 
        dataType: 'json', 
        error: this.requests[x].error, 
        method: 'GET' 
       }).done(success);     
      } 

     } 

    }; 
}; 

그리고 여기 내가 사용하는 방법은 다음과 같습니다

var apiUrl = Utilities.Api.GetWebApiUrl(); 
var loader = new Utilities.ResourceLoader(); 

loader.Add({ 
    url: apiUrl + 'regions/get', 
    success: function (results) { 
     Filters.Regions = results; 
    } 
}); 

loader.Add({ 
    url: apiUrl + 'currentfactors/get/83167', 
    success: function (results) { 
     Filters.NbrEmployees = results; 
    } 
}); 

loader.Add({ 
    url: apiUrl + 'currentfactors/get/83095', 
    success: function (results) { 
     Filters.Industries = results; 
    } 
}); 


loader.FinalCallback = RenderBody; 
loader.Execute(); 

function RenderBody() { 
    console.log('render...'); 
} 

을 분명히, 나는 RenderBody가 마지막으로 실행 될 것으로 기대하고있다. 하지만 그건 무슨 일이 아니야. 아이러닉 한 점은 이전에 그런 식으로 일하는 것을 기억하지만 코드를 잃어버린 것입니다 ... 내가 뇌간을 가지고있는 것처럼 보입니다.

+0

'내가 RenderBody를 기다리고있을 때 jQuery를 사용하여 Promise.all

this.Execute = function() { Promise.all(this.requests.map(function(request) { return $.ajax({ url: request.url, dataType: 'json', error: request.error, method: 'GET' }).done(request.success); })).then(this.FinalCallback); }; 

나 ...를 사용하는 정말 깨끗한 솔루션입니다 '문제는, 당신이 지적한 것처럼, 비동기 요청은 순차적으로 발생하지 않기 때문에 요청이 최종 것인지 아닌지 확인하기보다는 응답 *이 ​​최종 것인지 확인하십시오 –

+0

HTTP 요청이 끝나면 끝납니다. 보증 된 주문이 없습니다. 자신의 카운터를 유지하고 "성공"콜백에서 증가시켜 최종 응답을 처리하는 시점을 알 수 있습니다. – Pointy

+0

@Pointy 그래서'ResourceLoader'에서 제공되는 성공 콜백에 카운터 체크를 주입해야합니까? 나는 이것을 처리하기 위해'ResourceLoader'를 원한다. –

답변

2

당신은 태그했듯이 - 여기에 마지막으로 실행되는

this.Execute = function() { 
    $.when.apply($, this.requests.map(function(request) { 
    return $.ajax({ 
     url: request.url, 
     dataType: 'json', 
     error: request.error, 
     method: 'GET' 
    }).done(request.success); 
    })).then(this.FinalCallback); 
}; 
+0

아직 시도하지 않았습니다. 실제로 깨끗해 보입니다. 가장 최근의 브라우저와 얼마나 호환됩니까? (IE, Edge, Chrome 등)? –

+0

Promise polyfill이없는 IE가 없습니다 ([OK polyfill]에 대한 링크는 [MDN promise page] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise#See_also 참조) (https://github.com/jakearchibald/es6-promise/) ... 또는 어쩌면 [bluebird] (http://bluebirdjs.com/docs/getting-started.html)를 사용하십시오. 하지만 나는'jquery.when' 대안으로 업데이트했습니다 - IE에 문제가 있어서는 안됩니다 –

+0

고마워요, 완벽하게 작동합니다. 지금 jQuery 대안을 고수 할 것입니다. –

0

Es6 Promise에는 문제를 해결할 수있는 솔루션이 있습니다. 자원 그룹을로드하는 것이 특정 목표 인 경우를 제외하고는 재발견 할 필요가 없습니다. 생성자를 사용하여 XHR에 대한 해결 및 거부 콜백을 적절하게 할당하여 각 리소스 요청에 대해 Promise 개체를 설정합니다. 컬렉션을 개의 결과 (Iterable 할 예정)로 유지하십시오. 최종 제품은 Promise.all(collectionOfPromises).then(finalCallback)입니다.

관련 문제