如何将嵌套回调转换为jQuery承诺

时间:2014-08-01 09:32:28

标签: jquery google-maps promise

现在我需要通过谷歌地图计算每个房子的距离。

var campus = {loc: [-122.4579294, 37.7632498]}
var homes = [
    {loc: [-122.4629668, 37.75962]},
    {loc: [-122.4629672, 37.75960]}
    //...
]

function distanceReady(msg) {
    var type = msg.type
    var distance = 0

    home[type] = home[type] || []
    home[type].push(msg)

    $.each(home[type], function(index, value) {
        distance += value.distance.value
    })

    home[type].allDistance = distance / 1000 * 0.62
}

function caculateRoute(transType, home) {
    var campusLoc = campus.loc
    var homeLoc = home.loc

    // the map is google map object by gmaps
    map.travelRoute({
        origin: [homeLoc[1], homeLoc[0]],
        destination: [campusLoc[1], campusLoc[0]],
        travelMode: transType,
        step: function(e) {
            distanceReady({
                type: transType,
                distance: {
                    text: e.distance.text,
                    value: e.distance.value
                },
                step_number: e.step_number,
                duration: e.duration,
                path: e.path,
                instructions: e.instructions,
                direction: {
                    left: e.instructions.indexOf('left') > -1,
                    right: e.instructions.indexOf('right') > -1
                }
            })
        }
    })
}

$.whenall = function(arr) {
    return $.when.apply($, arr)
}

var deferreds = []

for (var i = 0, l = homelist.length; i < l; i++) {
    var home = homelist[i]

    // I have no idea how to wrap the caculateRoute function into a promise
    // and then each deferred return its allDistance
    // var deferred = caculateRoute('transit', home)
    // deferreds.push(deferred)
}

$.whenall(deferreds).done(function() {
    for (var i = 0; i < arguments.length; i++) {
        var distance = arguments[i]
    }
})

所以,我可以要求每个家庭获取距离,然后我需要所有距离完成所有这些。如何包装caculateRoute并修改distanceReady函数,以便我可以在$ .whenall(deferreds).done中获取它们的距离。

1 个答案:

答案 0 :(得分:0)

在阅读了jQuery Deferred和google-maps的api后,我终于找到了出路。这是代码:

function distanceReady(home, msg) {
  var type = msg.type
  var distance = 0
  var duration = 0

  home[type] = home[type] || []
  home['has' + type] = true
  home[type].push(msg)

  $.each(home[type], function(index, value) {
    distance += value.distance.value
    duration += value.duration.value
  })

  home.distance = distance / 1000 * 0.62
}

function caculateRoute(home, defer) {
  var transType = 'driving'
  var campusLoc = campus.loc.coordinates
  var homeLoc = home.loc.coordinates

  map.travelRoute({
    origin: [homeLoc[1], homeLoc[0]],
    destination: [campusLoc[1], campusLoc[0]],
    travelMode: transType,
    step: function(e) {
      distanceReady(home, {
        type: transType,
        distance: {
          text: e.distance.text,
          value: e.distance.value
        },
        step_number: e.step_number,
        duration: e.duration,
        path: e.path,
        instructions: e.instructions,
        direction: {
          left: e.instructions.indexOf('left') > -1,
          right: e.instructions.indexOf('right') > -1
        }
      })
    },
    end: function(e) {
      defer.resolve()
    }
  })

  return defer
}

$.whenall = function(arr) {
  return $.when.apply($, arr)
}

function caculateDistance(homelist, cb) {
  var deferreds = []

  for (var i = 0, l = homelist.length; i < l; i++) {
    var home = homelist[i]
    var defer = $.Deferred()

    deferreds.push(caculateRoute(home, defer))
  }

  $.whenall(deferreds).done(function() {
    console.log('done')
    cb()
  })
}

只有一个我无法解决的问题。似乎google route service将搜索时间限制在8~10之间,如果房屋超过10,则总是会失败。

可以在这里找到:

Google Map API Route Request limit