2014-12-27 76 views
0

任何人都可以解釋我如何deffered部分工作在這個代碼?延遲傳遞值如何?

(function() { 

var getPosition = function (options) { 
    var deferred = $.Deferred();  
    navigator.geolocation.getCurrentPosition(
     deferred.resolve, 
     deferred.reject, 
     options);  
    return deferred.promise(); 
}; 

var lookupCountry = function (position) { 
    var deferred = $.Deferred();  
    var latlng = new google.maps.LatLng(
         position.coords.latitude, 
         position.coords.longitude); 
    var geoCoder = new google.maps.Geocoder(); 
    geoCoder.geocode({ location: latlng }, deferred.resolve);  
    return deferred.promise(); 
}; 

var displayResults = function (results, status) {    
    $("body").append("<div>").text(results[0].formatted_address);  
}; 

$(function() { 
    $.when(getPosition()) 
    .pipe(lookupCountry) 
    .then(displayResults); 
});  
}()); 

我對上面的代碼是如何工作的幾個問題..

$(function() { 
    $.when(getPosition()) 
    .pipe(lookupCountry) 
    .then(displayResults); 
}); 
  1. 如何不經過options上面的代碼仍然可以工作?如何將position傳遞給lookupCountry()方法?
  2. 如果在getPosition函數中deferred.reject被觸發將會發生什麼?
+0

什麼你問的是真的,爲什麼當一個函數被引用的參數自動傳遞,而不是所謂 – adeneo 2014-12-27 14:15:42

+0

@adeneo這裏一個有趣的事情做的是,它似乎「解決「和」拒絕「回調內在綁定到每個延遲實例。我不知道。或者,也許內臟不會依賴'this'。 – Pointy 2014-12-27 14:23:20

+0

@Pointy - 是的,它們綁定到每個實例,並且可以根據需要創建多個實例。過去你會稱之爲'var def = new $ .Deferred()',但現在它在內部執行,就像'$()'檢查它是否是一個instanceof本身並且自動返回'new'關鍵字。當你調用它時,你不必實際寫出「新」,這是一個非常好的做法。 – adeneo 2014-12-27 14:26:35

回答

1

第一個函數getPosition被調用時沒有參數,但這很好,因爲HTML5地理定位API不需要選項對象來工作。

navigator.geolocation.getCurrentPosition()預計成功回調(一個函數)作爲其第一個參數。在這種情況下,該函數是deferred.resolve(),它接收並傳遞它接收到鏈下一步的所有參數。由於它收到一個有效的位置,所以傳遞給lookupCountry

lookupCountry將該位置變成google.maps.LatLng對象,該對象將提供給google.maps.GeoCoder()反向地理定位調用,該調用也期望成功執行回調函數。在這種情況下,它會將一組地址傳遞給鏈中的下一個步驟。

displayResults將接收到一組地址對象,挑選第一個地址對象並顯示其格式化地址。

上面的代碼神奇地工作。每個功能在期望的位置接收預期的參數。如果代碼被修改,lookupCountry預期,例如,作爲第一個參數評論:

var lookupCountry = function (comment, position) { 
    ... 
} 

就不會了,因爲它不能只是猜測每個參數的含義工作。

我不確定以上是否是延期使用的好例子。整個上面的代碼可以用

$(function() { 
    navigator.geolocation.getCurrentPosition(function (position) { 
     var geoCoder = new google.maps.Geocoder(); 
     geoCoder.geocode({ 
      location: { 
       lat: position.coords.latitude, 
       lng: position.coords.longitude 
      } 
     }, function (results) { 
      $("body").append("<div>").text(results[0].formatted_address); 
     }); 
    }); 
}); 
+0

如果在getPosition函數中觸發deferred.reject會發生什麼情況,管道在這裏做什麼?那不可能是另一個呢? – Shane 2014-12-27 15:09:22

+0

如果地理定位失敗,則不會觸發成功回調。永遠。但是你的原始功能也不處理拒絕。我想他們都需要顯示一條消息,比如「抱歉,我們無法確定您的位置,您的瀏覽器不支持它,或者您不允許它」。根據使用兩個「那麼」它也是可能的,但他們將不得不嵌套,你需要一秒鐘。 – amenadiel 2014-12-27 15:13:26

+0

「但他們必須嵌套,你需要一秒鐘,」 - 赦免!? (a)問題的「.when(...)」是不必要的,這將是第二個; (b)嵌套可能是有用的,但'.then(...)。then(...)'完全有效。 – 2014-12-27 17:13:14