从函数内部所需的数据填充空对象?

时间:2016-01-09 23:45:24

标签: javascript jquery

只想在myObj中填充get请求中的数据。根据我的console.log(myObj),每个人似乎都是他们的但无法访问。我确定他们的答案很简单。谢谢。

function getInfo() {
  var myObj = {};
  $.get("http://ipinfo.io", function(response) {
    myObj.city = response.city;
    myObj.region = response.region;
  }, "jsonp");
  console.log(myObj.city);  //undefined
  return myObj;
}

var myStuff = getInfo();  //Object {} just as I expected obviously.
console.log(myStuff)  // Object shows all my key value pairs but -->
console.log(myStuff.city);  // undefined  why? 

3 个答案:

答案 0 :(得分:2)

更适合使用承诺。你可以尝试这样的事情:

function getInfo() {
  var dfd = $.Deferred();

  $.get("http://ipinfo.io", function(response) {
    myObj.city = response.city;
    myObj.region = response.region;
    dfd.resolve(myObj);
  }, "jsonp");

  // Return the Promise so caller can't change the Deferred
  return dfd.promise();
}

getInfo().done(function(myStuff) {
  console.log(myStuff);
  console.log(myStuff.city);
});

凭借承诺,代码是一个优雅的想法。

答案 1 :(得分:1)

它返回undefine,因为请求没有响应,然后函数返回了值。您的请求是异步的,这意味着您的函数不会等待您的get请求。它会返回myObj。

您可以尝试类似

的内容
function getInfo(callback){
     $.get(..., function(res){
            var myObj = …;
             callback(myObj);
     }
}

当您的请求完成时,它将调用回调函数并传入myObj。所以你需要传入一个匿名函数,该函数期望1个参数从响应中传递myObj

getInfo(function(data){
    //data should be myObj
});

答案 2 :(得分:1)

$.get是一个异步操作,这意味着它立即返回(不首先在回调函数中运行代码)。只有GET请求完成后,才会在将来的某个时刻执行回调。与此同时,$.get调用后的代码将被执行。

您所看到的是特定执行顺序的结果,其中GET请求在执行以下代码之前未完成。换句话说,你有race condition

理论上,如果GET请求几乎立即完成,则回调可能会在日志语句之前执行,因此不会打印undefined。然而,这是不太可能的,因为执行日志指令所花费的时间比执行GET请求所需的时间少得多(!)。

要解决此问题,您需要确保在 GET请求完成后,总是 在JS中执行此操作的惯用方法是使用回调 - 例如传递一个包含要执行的代码的函数,并从响应处理程序中调用它:

function getInfo(callback) {
  var myObj = {};
  $.get("http://ipinfo.io", function(response) {
    myObj.city = response.city;
    myObj.region = response.region;
    callback(myObj);
  }, "jsonp");
  console.log(myObj.city);  //undefined
}

getInfo(function(myStuff) {
    console.log(myStuff)
    console.log(myStuff.city);
});