如何从函数中获取 API 响应数据?

How can I obtain API response data from within a function?

Javascript 菜鸟在这里。如果那里有大量重复的问题,我深表歉意,因为看起来这一定是一个基本的 js 函数,但老实说我找不到答案。我正在尝试将 API GET 调用包装在一个函数中,但我 运行 陷入了我不理解的行为。有问题的代码:

我正在使用 node-rest-client 包来调用 mapquest 地理编码 API。我只对 lat/long 数据感兴趣。
var Client = require('node-rest-client').Client;

如果我像这样进行 GET 调用,我可以将 parsed 作为对象访问,这正是我想要的。

var address = 'New York'
var client = new Client();
var parsed;
client.get("http://www.mapquestapi.com/geocoding/v1/address?" +
                'key=' + mapquestKeys.consumer_key +
                '&location=' + address,
            function(data, response) {
              parsed = data.results[0].locations[0].latLng
              }
            );

// parsed == {lat, long}

但是如果我把它包装在一个函数中:

function geocode(address){
  var client = new Client();
  var parsed;
  client.get("http://www.mapquestapi.com/geocoding/v1/address?" +
                  'key=' + mapquestKeys.consumer_key +
                  '&location=' + address,
              function(data, response) {
                parsed = data.results[0].locations[0].latLng
                }
              );
    return parsed
}

var address = 'New York'
parsed = geocode(address);

// parsed === undefined

parsed 似乎不受内部函数的影响;它是未定义的。我如何 return parsed 作为包含我想要的数据的对象,如第一个示例?这到底是怎么回事?

您从未在范围内(函数外部)定义 parsed:

function geocode(address){
  var client = new Client();
  var parsed;
  client.get("http://www.mapquestapi.com/geocoding/v1/address?" +
                  'key=' + mapquestKeys.consumer_key +
                  '&location=' + address,
              function(data, response) {
                parsed = data.results[0].locations[0].latLng
                }
              );
    return parsed
}

var address = 'New York'
var parsed = geocode(address);

注意 var parsed = geocode(address);

您需要将其包装到一个承诺中,或者 return 带有回调的结果。回调将是这样的:

function call(arg, callback) {
 client.get("http:////" + arg, function (data, response) { 
  callback(data.results[0].locations[0].latLng)
 });
}

call("yolo", function (parsed) { console.log(parsed) })

承诺在这里得到了很好的描述:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

在:

function geocode(address){
  var client = new Client();
  var parsed;
  client.get("http://www.mapquestapi.com/geocoding/v1/address?" +
                  'key=' + mapquestKeys.consumer_key +
                  '&location=' + address,
              function(data, response) {
                parsed = data.results[0].locations[0].latLng
                }
              );
    return parsed
}

var address = 'New York'
parsed = geocode(address);

// parsed === undefined

您从未在函数范围之外定义 parsed。此外,在函数有机会从 GET 请求中检索之前,您还在函数内部 returning parsed 。如果你想这样做,你需要将 return(prased) 放在 client.get 的回调函数中。更好的方法是像这样将它包装在 Promise 中:

function geocode(address){
    return new Promise((resolve, reject) => {
        var client = new Client();
        client.get("http://www.mapquestapi.com/geocoding/v1/address?" +
                'key=' + mapquestKeys.consumer_key +
                '&location=' + address,
                function(data, response) {
                if(data){
                    resolve(data.results[0].locations[0].latLng)
                }
                else{
                    reject(response)
                }
                  });
    })
  };


var address = 'New York';
var parsed;
geocode(address).then(function(latlong){
    parsed = latlong
}).catch(err => {
    console.log(err)});

这里,一旦 Promise 被解析(GET 请求已 return 成功),parsed 将只评估为 latlong。如果 GET 请求的数据为 NULL 并且 return 错误,它也会拒绝 Promise。

如果您想用 parsed 做一些事情,您可以将其包含在 .then() 语句中。

学习如何在 Javascript 中编写代码意味着学习如何编写代码 异步 。 Promises 帮助您将默认 异步 的事物视为 同步.