2014-12-27 94 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