在Node.js / Express.js中使用变量超出回调函数的范围

时间:2018-04-02 17:30:42

标签: javascript node.js express

我在快递js中使用名为node-geocoder的库,其中包含以下代码:

var NodeGeocoder = require('node-geocoder');

var options = {
  provider: 'google',

  // Optional depending on the providers
  httpAdapter: 'https', // Default
  apiKey: 'YOUR_API_KEY', // for Mapquest, OpenCage, Google Premier
  formatter: null         // 'gpx', 'string', ...
};

var geocoder = NodeGeocoder(options);

// Using callback
geocoder.geocode('29 champs elysée paris', function(err, res) {
  console.log(res);
});

地理编码方法的回调函数中的响应变量(res)包含一个具有位置属性(如latitutde和longitude)的对象。此程序包的链接为here

我想知道是否有办法在地理编码方法中的回调函数之外使用该响应变量。我需要提取纬度和经度属性,我不想将其余代码保留在该回调函数中。

作为一个菜鸟我尝试返回对象并将其存储在一个变量中:

var object = geocoder.geocode('29 champs elysée paris', function(err, res) {

   return res;

});

这不起作用,因为它在回调中而不是在实际的地理编码方法中返回。

4 个答案:

答案 0 :(得分:1)

不是直接的,但有几个选项可以接近它。

一种方法是让你的回调成为一个已定义的函数,并将其用作回调函数:

const doSomething = (err, res) => { /* do something */ }

geocoder.geocode('abc', doSomething);

没有太大的不同,但可以使它更清洁。

您还可以“宣传”该功能,让它返回Promise。像这样的东西可以解决这个问题:

const geocodePromise = (path) => new Promise((resolve, reject) => {
    geocoder.geocode(path, (err, res) => err ? reject(err) : resolve(res));
});

geocodePromise('abc')
  .then(res => { /* do something */ })
  .catch(err => { /* do something */ });

最后,如果您使用Babel进行转换(或者使用本机版本的7.6.0或更高版本的Node版本),则可以使用asyncawait。使用与上述函数相同的promisified版本,您必须将主代码包装在async函数中。我通常使用自调用匿名函数:

(async () => {
  try {
    const res = await geocodePromise(path);

    /* do something with res */
  } catch (err) {
    /* do something with err */
  }
})();

有了这个,你得到了最接近你想要的东西,但你仍然需要将你的主代码包装在一个函数中,因为你不能在顶层await

答案 1 :(得分:0)

您可以通过调用另一个函数来使用回调之外的函数响应。

import "github.com/Arachnid/solidity-stringutils/strings.sol";

答案 2 :(得分:0)

  

我不想将其余代码保留在该回调函数中。

代码不必是 in 回调,只需从回调中调用

所以你正常编写你的函数(或函数):

function handleInfo(info) {
    doSomethingWithInfo(info);
    doSomethignElse(info);
    // ...
}
// ...

...然后在获得数据时调用这些函数:

geocoder.geocode('29 champs elysée paris', function(err, info) {
  if (err) {
      // Handle error
  } else {
      handleInfo(info);
  }
});

答案 3 :(得分:0)

geocode已经可以返回promise,无需重新包装它。如果您不关心错误,只想获取响应的位置数据。你可以这样做

var locationData = geocoder.geocode('29 champs elysée paris').then( function(res){
    return res;
});