简体   繁体   English

在node.js中返回延迟的嵌套promise

[英]return a delayed nested promise in node.js

I am using Google geocoding in my code. 我在我的代码中使用Google地理编码。 I have to geocode about 50 places, but Google doesn't allow to geocode so many places at the same time, generating a 'OVER_QUERY_LIMIT' error. 我必须对大约50个地方进行地理编码,但Google不允许同时对这么多地方进行地理编码,从而产生“OVER_QUERY_LIMIT”错误。 So I want do delay the geocoding for few seconds when I exceed the quota. 因此,当我超过配额时,我希望延迟地理编码几秒钟。 I have a function geocode() that returns a promise . 我有一个返回promise的函数geocode() When I exceed quota, I want to recursively call itself. 当我超过配额时,我想以递归方式调用自己。

This is my not-working code: 这是我不能正常工作的代码:

function geocodeAll(addresses)
 {
   for (addr in addresses)
     {
      geocode(addresses[addr])
        .then(
              function(coord)
               {/* I don't always get here */}
             )
     }
 }


function geocode(address)
{
 var deferred = Q.defer();
 geocoder.geocode(address, function ( err, geoData ) 
        {
         if (err)
            { deferred.reject(err);}
         else
            {
             if (geoData.status=="OVER_QUERY_LIMIT" )
                 { // doh! quota exceeded, delay the promise
                  setTimeout(function()
                     {geocode(address)
                      .then(
                            function(coord)
                             {deferred.resolve(coord);}
                           );
                      }, 1000);
                    }
                else
                    { // everything ok
                     var coord = {'lat':geoData.lat, 'lng':geoData.lng};              
                     deferred.resolve(coord);
                    }
               }
      });

  return deferred.promise; 
}

UPDATE [solved] 更新[已解决]

actually the code is right. 实际上代码是对的。 I had an uncaughtException not related to the delay. 我有一个与延迟无关的未被捕获的异常。 Using Q.all([..]).then().catch() I found it 使用Q.all([..]).then().catch()我找到了它

Your code seems to work fine. 你的代码似乎工作正常。 The only issue i see with your code is that you are using lat and lng out of scope. 我看到你的代码唯一的问题是你使用latlng超出范围。 But you may have written that correctly and you're just not including the code. 但是你可能已经正确地写了这些,而你只是不包括代码。 I suspect though that you may have been using the two in error. 我怀疑你可能错误地使用了这两个。 Should those have been geoData.lat and geoData.lng ? 这些应该是geoData.latgeoData.lng吗?

var coord = { 'lat': geoData.lat, 'lng': geoData.lng };

Plnkr Plnkr

EDIT 编辑

I think your problem might have to do with your geocodeAll function implementation. 我认为您的问题可能与您的geocodeAll函数实现有关。

function geocodeAll(addresses)
 {
   for (addr in addresses)
     {
      geocode(addresses[addr]) /* This seems error prone to me!  Try keeping track of all your promises.*/
        .then(
              function(coord)
               {/*You only get here if there was no error returned from the geo request to the api. */}
             )
     }
 }

Keep track using Q.all , 使用Q.all跟踪,

function geocodeAll(addresses) {
  var promises = addresses.map(geocode); 
  for (addr in addresses) {
    promises.push(
      geocode(addresses[addr])
         .catch(console.log.bind(console)) /* handle your error however you see fit*/
      ); 
  }
  return Q.all(promises).then(function(results) {
     var firstCord = results[0];
     var secondCord = results[1];
     //etc...
  });
 }

Or you can additionally handle the success/fail using Q.allSettled 或者您可以使用Q.allSettled另外处理成功/失败

function geocodeAll(addresses) {
      var promises = addresses.map(geocode);
      return Q.allSettled(promises).then(function (results) {
        var success = [], fail = [];
        results.forEach(function (result) {
          if (result.state === "fulfilled") {
             success.push(result.value);
          } else {
            fail.push(result.reason);
          }
        });
        return { coords: success, errors: fail };
      });
     }

   });

Code looks good. 代码看起来不错。 Perhaps geocoder.geocode or something else is erring. 也许geocoder.geocode或其他东西犯了错误。 Try setting: 尝试设置:

window.onerror = (err) => console.error(err)

Or: 要么:

process.on('uncaughtException', (err) => console.error(err))

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

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