2015-01-08 3 views
0

나는 long lat 사용자를 얻는 함수가 있습니다. url이 다를 사용자 위치를 기반으로 URL을 반환하도록해야합니다. 반환 된 url은 ajax 호출에서 사용됩니다. 그러나이 두 번째 아약스 호출은 내 첫 번째 함수가 끝나기 전에 치명타를 당해 URL이 정의되지 않았기 때문에 404를 제공합니다.javascript/jquery에서 함수 실행

그래서 내 코드는 다음과 같습니다

$(document).ready(function() { 
    getLatLong(); 

    if (!hasTicket) { 
     doAction(); 
    } else { 
     doAnotherAction(); 
     $.unblockUI(); 
    } 
}); 

function doAction() { 
     $.ajax({ 
      url: url, // this is where I am failing 
      type: 'POST', 
      success: function (response) { 
       ticket = response.data.ticket; 
       $.unblockUI(); 
      }, 
      error: function (xhr) { 
       $.unblockUI(); 
       errorHandler("Failed" + xhr.status); 
      } 
     }); 
} 

function getLatLong() { 
    if (Modernizr.geolocation) { 
     navigator.geolocation.getCurrentPosition(
      function (position) { 
       getUrl(position.coords.latitude, position.coords.longitude); 
      }, 
      getUrlFallback, 
      { enableHighAccuracy: false, timeout: 10000, maximumAge: 360000 } 
     ); 
    } else { 
     getUrlFallback(); 
    } 
} 

function getUrl(latitude, longitude) { 
    $.ajax({ 
     url: 'api/Controller/Action', 
     type: 'GET', 
     async: false, // tried making this synchronous 
     data: { 
      latitude: latitude, 
      longitude: longitude 
     }, 
     success: function (data) { 
      url = data; 
     }, 
     error: function (xhr) { 
      errorHandler("Failed to get users nearest url: " + xhr.status); 
     } 
    }); 
} 

그래서 그때 그러나 내가 처음 내 doAction 함수가 호출되는으로하고 getLatLong에서 돌아 생각 false로 비동기 세트가 내의 getURL 아약스 함수를 호출 getLatLong를 호출 그러면 URL이 정의되지 않게됩니다.

doAction이 실행되기 전에 getLatLong 및 getUrl이 완전히 종료되도록하려면 어떻게해야합니까?

getLatLong() 호출 후 발생하는 기능을 복사하려고했습니다. 함수로 만들고 $ .when adn을 사용하면 다음과 같이됩니다. 그러나 URL이 설정되기 전에 여전히 doAction 메소드에 들어갑니다.

$(document).ready(function() { 

    $.when(getLatLong()).then(callAction()); 
}); 

편집 - getUrlFallback 기능을 업데이트 당신은 jQuery를 Promise을 반환하도록 getLatLong 전화를 변환 할 수 있습니다

function getUrlFallback() { 
    // uses 3rd party geoPlugin 
    getUrl(geoplugin_latitude(), geoplugin_longitude()); 
} 
+2

Ajax 비동기를 중지해야합니다. http://stackoverflow.com/questions/1478295/what-does-async-false-do-in-jquery-ajax 또는 성공 내에서 두 번째 함수를 호출 할 수 있습니다. 첫 번째 Ajax 함수의 함수 (데이터) –

+3

I wouldn ' 그는 비동기를 멈추고 대신 효과적으로 패턴을 사용하도록 바꾼다. –

+0

@DawoodAwan 아니오, 동기가 _not_ 정답입니다! – Alnitak

답변

1

:

function callAction() { 
     if (!hasTicket) { 
      doAction(); 
     } else { 
      doAnotherAction(); 
      $.unblockUI(); 
     } 
} 

후 나는 준비 아래의 문서를했다 :

(NB : 저는를 포함하고 있지 않습니다. 당신이 그 코드 그래서 내가 말할 수 없습니다 포함하지 않은 여기논리 무엇의) 어떻게해야 :

function getLatLong() { 
    return $.Deferred(function(def) { 
     if (!Modernizr.geolocation) { 
      def.resolve(geoplugin_latitude(), geoplugin_longitude()); 
     } else { 
      navigator.geolocation.getCurrentPosition(
       function(position) { 
        def.resolve(position.coords.latitude, position.coords.longitude); 
       }, 
       def.resolve(geoplugin_latitude(), geopugin_longitude()), 
       { enableHighAccuracy: false, timeout: 10000, maximumAge: 360000 } 
      ); 
     } 
    }).promise(); 
} 

을 또한 getUrl 같은 그것이 return의 결과 $.ajax의 수정 및 success를 생략하고 error 콜백 :

function getUrl(latitude, longitude) { 
    return $.ajax(...); 
} 

그래서 당신은 지금 사용할 수 있습니다

getLatLong().then(getUrl).then(callAction); // NB: no() after callAction 

callAction은 외부 범위의 변수에 저장되는 대신 URL을 자동으로 전달합니다.

이제는 getLatLong 기능이이 기능을 수행하는 방식에 유의하십시오. URL이 GeoAPI 또는 geoplugin인지 여부에 관계없이 getUrl이 위도/경장을 URL로 변환하려고 시도하지 않습니다.

+0

getUrlFallback 함수를 사용하여 updtaed했습니다. 어떻게 표시해야하는지에 대한 답을 편집 할 수 있습니까? 이제 prmoises 함수 – TheRiddler

+0

및 getUrl에서 $ .ajax를 반환하도록 표시 한 곳에서 async : false를 제거해야합니까? – TheRiddler

+0

@TheRiddler 예 - 분명히 'async : false'를 제거합니다. - 나는 당신 자신의 코드에서 그것을 멈추지 않았습니다. 'getUrlFallback' 비트를 보겠습니다. – Alnitak