【问题标题】:Using a Variable Out of Scope of a Callback Function in Node.js / Express.js在 Node.js / Express.js 中使用超出回调函数范围的变量
【发布时间】:2018-04-03 02:38:46
【问题描述】:

我在 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);
});

geocode 方法的回调函数中的响应变量(res) 保存一个对象,该对象具有纬度和经度等位置属性。这个包的链接是here

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

作为一个菜鸟,我尝试只返回对象并将其存储在一个变量中,如下所示:

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

   return res;

});

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

【问题讨论】:

  • 解决它的一种方法是从回调中调用一个函数。请参阅下面的答案

标签: javascript node.js express


【解决方案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 进行转译(或 Node 版本 7.6.0 或更高版本,它本身就有),你可以使用 asyncawait。使用与上述函数相同的承诺版本,您必须将主代码包装在 async 函数中。我通常为此使用自调用匿名函数:

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

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

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

【讨论】:

    【解决方案2】:

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

    代码不必回调中,它只需要回调中调用。

    所以你像往常一样编写你的函数(或函数):

    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】:

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

      geocoder.geocode('29 champs elysée paris', function(err, res) {
        if(!err){
          // call a function if there is no error
          console.log(res);
          myFunction();
        }
       });
      
      function myFunction(){
       //do your processing here
      }
      

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-11-12
          • 2020-07-22
          • 1970-01-01
          相关资源
          最近更新 更多