简体   繁体   English

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

[英]Using a Variable Out of Scope of a Callback Function in Node.js / Express.js

I am using a library called node-geocoder in express js which has the following code: 我在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);
});

The response variable(res) in the geocode method's callback function holds an object with location properties such as latitutde and longitude. 地理编码方法的回调函数中的响应变量(res)包含具有位置属性(例如纬度和经度)的对象。 The link for this package is here 该软件包的链接在这里

I was wondering if there was a way to use that response variable outside of the callback function in the geocode method. 我想知道在geocode方法的回调函数之外是否可以使用该响应变量。 I need to pull the latitude and longitude properties and I don't want to keep the rest of the code within that callback function. 我需要拉出经度和纬度属性,并且我不想将其余代码保留在该回调函数中。

As a noob I tried just returning the object and storing it in a variable like so: 作为菜鸟,我尝试仅返回对象并将其存储在变量中,如下所示:

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

   return res;

});

This doesn't work since it's in the callback and not returned in the actual geocode method. 这不起作用,因为它在回调中,并且在实际的地址解析方法中未返回。

Not directly, but there are a couple of options to get closer to that. 并非直接如此,但是有两种选择可以实现这一目标。

One would be to have your callback be a defined function and use that as the callback: 一种方法是让您的回调成为已定义的函数,并将其用作回调:

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

geocoder.geocode('abc', doSomething);

Not really much different, but can make it a little cleaner. 并没有太大的区别,但是可以使其更清洁。

You can also "promisify" the function to have it return a Promise . 您也可以“承诺”该函数以使其返回Promise Something like this would do the trick: 这样的事情可以解决问题:

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 */ });

Finally, if you are using Babel for transpiling (or Node version 7.6.0 or higher, which has it natively), you can use async and await . 最后,如果您使用Babel进行转译(或本身具有此功能的Node版本7.6.0或更高版本),则可以使用asyncawait Using the same promisified version of the function as above, you'd have to wrap your main code in an async function. 使用与上述函数相同的承诺版本,您必须将主代码包装在async函数中。 I generally use a self-calling anonymous function for that: 我通常为此使用自调用匿名函数:

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

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

With this, you get the closest to what you want, but you'll still have to wrap your main code up in a function because you can't await at the top level. 这样,您就可以最接近所需的内容,但仍必须将主代码包装在一个函数中,因为您无法await顶层。

You can use the response of your function outside the callback by calling another function. 您可以通过调用另一个函数在回调之外使用函数的响应。

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
}

I don't want to keep the rest of the code within that callback function. 我不想将其余代码保留在该回调函数中。

The code doesn't have to be in the callback, it just has to be called from the callback. 代码并不一定是回调,只是必须回调调用。

So you write your function (or functions) as normal: 因此,您可以正常编写函数(或多个函数):

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

...and then call those functions when you have the data: ...然后在拥有数据时调用这些函数:

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

geocode can return promise already, no need to re-wrap it. geocode已经可以返回承诺,而无需重新包装。 If you don't care about the error and just want to grab the response's location data. 如果您不关心错误,而只想获取响应的位置数据。 You can do this 你可以这样做

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM