使用jquery.when和done将值从一个ajax调用传递给另一个

时间:2016-04-24 07:08:42

标签: javascript jquery ajax asynchronous promise

我试图在第二个ajax调用中使用第一个ajax调用的值。我正在使用下面的代码结构。出于某种原因,第二次通话会为undefined userLocation返回variable。我怎么能重构我的代码,以便第一个ajax调用的userLocation值可以在第二个ajax调用的url中使用?

var userLocation;

function getUserLocation() {
  $.ajax({
    url: 'https://www.example.com/location.json',
    success: function(response) {
      userLocation = response.coordinates;
    }
  });
}

function getCurrentWeather() {
  $.ajax({
    url: 'https://www.example.com/weather' + userLocation +  '.json',
    success: function(response) {
      console.log(response);
    }
  });
}


$(document).ready(function() {
  $.when(
    getUserLocation()
  ).done(
    getCurrentWeather()
  )
});

更新1: 感谢下面提供的答案,我已经能够重构我的代码。现在,从第一个ajax调用接收的值可以在第二个ajax调用中使用。这是更新的代码:

var userLocation;

function getUserLocation() {
  return $.ajax('https://www.example.com/location.json')
  .then(function(response) {
    return JSON.parse(response);
  }).then(function(json) {
    // data from the location.json file is available here
    userLocation = json.coordinates;
  })
}

function getCurrentWeather() {
  return $.ajax('https://www.example.com/weather' + userLocation +  '.json');
}


getUserLocation().then(getCurrentWeather).then(function(data) {
  // data from the weather(userLocation).json file is available here
});

4 个答案:

答案 0 :(得分:9)

jQuery的ajax返回promises,你可以使用:

function getUserLocation() {
  return $.ajax('https://www.example.com/location.json'); // note the `return`
}

function getCurrentWeather(userLocation) {
  return $.ajax('https://www.example.com/weather' + userLocation +  '.json');
}

getUserLocation().then(getCurrentWeather).then(function(data) {
   // location data here
});

或者,更详细的

getUserLocation().then(function (user) { 
    return getCurrentWeather(user); 
}).then(function(data) {
   // location data here
});

更好的解决方案是将其作为单个调用而不是两个调用,因为许多AJAX调用会降低您的应用程序速度 - 尤其是在带宽有限的移动设备上。

这是一种基于回调的方法,可能不如基于承诺的方法(例如错误处理) - 但我觉得我们应该为完整性而展示它。您可以阅读有关常规解决方案in this thread的信息。

function getUserLocation(callback) {
  $.ajax('https://www.example.com/location.json', callback)
}

function getCurrentWeather(userLocation, callback) {
  $.ajax('https://www.example.com/weather' + userLocation +  '.json', callback);
}

getUserLocation(function(user) {
   getCurrentWeather(user, function(weather) {
       console.log("Got weather", weather); 
   });
});

答案 1 :(得分:2)

由于某种原因,第二次调用将返回userLocation变量的未定义

这是因为你没有从ajax电话中回复诺言,请参阅本杰明关于如何做到这一点的答案。

我怎样才能重构我的代码,以便第一个ajax调用的userLocation值可以在第二个ajax调用的url中使用?

重构您的代码以将调用嵌套到第一个调用中的其他函数:

var userLocation;

function getUserLocation() {
  $.ajax({
    url: 'https://www.example.com/location.json',
    success: function(response) {
      // set the user location
      userLocation = response.coordinates;
      // make call to second function passing in userLocation
      getCurrentWeather(userLocation);
    }
  });
}

function getCurrentWeather(userLocation) {
  $.ajax({
    url: 'https://www.example.com/weather' + userLocation +  '.json',
    success: function(response) {
      console.log(response);
    }
  });
}

$(document).ready(function() {
    getUserLocation()
});

如果你没有在其他任何地方使用变量userLocation,那么保存一些代码:

function getUserLocation() {
  $.ajax({
    url: 'https://www.example.com/location.json',
    success: function(response) {
      // make call to second function passing in coordinates from response
      getCurrentWeather(response.coordinates);
    }
  });
}

function getCurrentWeather(userLocation) {
  $.ajax({
    url: 'https://www.example.com/weather' + userLocation +  '.json',
    success: function(response) {
      console.log(response);
    }
  });
}

$(document).ready(function() {
    getUserLocation()
});

答案 2 :(得分:1)

你应该这样做:

function getUserLocation() {
  return $.ajax({
    url: 'https://www.example.com/location.json',
    success: function(response) {
      userLocation = response.coordinates;
    }
  });
}

function getCurrentWeather(userLocation) {
  return $.ajax({
    url: 'https://www.example.com/weather' + userLocation +  '.json',
    success: function(response) {
      console.log(response);
    }
  });
}


$(document).ready(function() {
  $.when(
    getUserLocation()
  ).done(
    getCurrentWeather
  )
});
  1. 从getUserLocation
  2. 返回$.ajax(...)
  3. getCurrentWeather作为一个函数传递,你不应该在完成后调用它,它将在getUserLocation完成后调用async。
  4. 编辑#2 :将getCurrentWeather()放入.done(...)时你做错了是这个函数会立即调用。但是,.done(...)应该传入一个函数,在解析$.when()承诺后将调用该函数。

    提到Benjamin Gruenbaum时,最好使用.done(...)然后.then(...)

答案 3 :(得分:0)

可以是这样的:

hadoop-env.sh