2016-09-15 3 views
0

아래의 비 기능적 예제는 내가하려고하는 것을 설명해야하며,이를 수행하는 데 필요한 패턴을 이해하지 못합니다. 인터넷 검색을 시도하여 폴링을 이해하고 지연 시켰지만 이해할 수있는 것을 찾을 수 없었습니다.

API를 폴링하는 기능이 있는데, 내 주요 기능을 계속하기 전에 해당 폴링이 예상 결과를 반환 할 때까지 기다렸다가 끝점이 변경되었다는 표시를 기다리고 싶습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

편집 : 제가 코드를 잘못 것 그 무엇을 추가해야합니다 아래, 비록 deferred.resolve() 결국 호출되는 것입니다 그것은 반환있어 같은 deferred 아니므로 whenmain() 활성화 결코 극복 보인다. 나는 그것이 시간 초과와 관련이 있다는 것을 짐작하고있다. 의미는 deferred 첫 반복에서 clobbered를 의미한다. 그것은 어쨌든 내 가정입니다.

function pollAPI() { 
    var deferred = $.Deferred(); 

    $.ajax({                 
     url: url,          
     contentType: 'application/JSON',          
     method: 'GET'               
    }).done(function(data){                                
     if (!desiredResult) {             
      setTimeout(function() {           
       pollAPI();        
      }, 1000);              
     } else {                
      deferred.resolve(); 
     }                                   
    }).error(deferred.reject());            

    return deferred.promise(); 
} 

function main() { 
    $.when(pollAPI()).then(function() { 
     // do something now that the API has returned the expected result 
    }); 
+0

pollAPI 호출 할 때마다 사방됩니다 새로운 연기, 아무것도 생성하지 - deferred.resolve (pollAPI())'시도'에서는 setTimeout –

+0

같으면 '에서을 첫 번째 연기가 해결되도록하는 원인이되어 준비가되지 않았지만 'when'을 트리거 할 수 있습니까? – fildred13

+0

예, 아직 해결되지 않은 약속으로 해결 될 것이므로 문제가되지 않아야합니다. [Promise/A + 사양] (https://promisesaplus.com/)의 2.3 절을 참조하십시오. jquery가이 사양을 따르기도하지만 거기 이전 jQuery 버전의 Promise/A + 스펙에서 크게 벗어났다. –

답변

2

당신은 그것에 체인 다른 사람이 하나의 약속을 만들 수 pollAPI() 기능에 대한 후속 호출의 체인을 사용할 수 있습니다. 즉 다음과 같이 작동합니다 :

// utility function to create a promise that is resolved after a delay 
$.promiseDelay = function(t) { 
    return $.Deferred(function(def) { 
     setTimeout(def.resolve, t); 
    }).promise(); 
} 

function pollAPI() { 
    return $.ajax({ 
     url: url, 
     contentType: 'application/JSON', 
     method: 'GET' 
    }).then(function(data) { 
     // some logic here to test if we have desired result 
     if (!desiredResult) { 
      // chain the next promise onto it after a delay 
      return $.promiseDelay(1000).then(pollAPI); 
     } else { 
      // return resolved value 
      return someValue; 
     } 
    }); 
} 

function main() { 
    pollAPI().then(function(result) { 
     // got desired result here 
    }, function(err) { 
     // ended with an error here 
    }); 
} 

이 다음과 같은 이점이 있습니다

  1. 없음 불필요한 약속은 이미 약속이있는 아약스 호출을 포위하려고 만들어지지 않습니다. 이렇게하면 common promise anti-patterns 중 하나가 발생하지 않습니다.
  2. API에 대한 후속 호출은 원래 약속으로 연결됩니다.
  3. 약속이 하나뿐일 때 $.when()을 사용할 필요가 없습니다. 그냥 .then()을 직접 사용할 수 있습니다.
  4. 모든 오류가 자동으로 원래 약속으로 돌아갑니다.
  5. 이 코드는 ES6 표준 인 .then()을 사용합니다. jQuery 3.x에서는 실제로 더 표준이되었습니다. jQuery 1.x와 2.x에서는 비표준적인 단점을 가지고 있지만)이 로직을 다른 약속 생성 비동기 함수. 또한

, 여기에 다른 시도 아이디어의 수 : Promise Retry Design Patterns

+0

이것은 다소 효과가 있으며, 참고 자료에 감사드립니다. 나는 그 패턴을 더 잘 이해하기 위해 그들을 통해 일하고있다. 내가 아직도 혼란스러워하는 유일한 부분은'return someValue'입니다. 반환하기 전에 someValue를 'foobar'로 설정하고 console.log (result)를 설정하면 콘솔에'undefined'가 출력됩니다.체인을 통해 값을 main()으로 반환하는 것에 대해 내가 오해하고 있습니까? – fildred13

+0

@ fildred13 -'someValue' (실제로 'someValue' 대신 실제 값을 넣는 곳)가'return someValue' 때문에 당신이 시도하고있는 것을 정확하게 보여 주어야합니다. 값을 원래의 약속으로 해석하고, 내가 보여준 코드를 사용한다면'main'에'result' 인자로 나타날 것입니다. – jfriend00

+0

오, 나는 틀린 것을 본다. 나에게있어, pollAPI()의 'then'은 i return'valueValue'라고 불릴 때조차도 호출되지 않는다. 기본적으로 pollAPI() 함수는 끝나지 만'then'은 호출되지 않습니다. 생각? – fildred13