javascript - 在 node.js 中返回一个延迟的嵌套 promise

标签 javascript node.js promise settimeout q

我在我的代码中使用了 Google 地理编码。我必须对大约 50 个地方进行地理编码, 但是谷歌不允许同时对这么多地方进行地理编码,从而产生“OVER_QUERY_LIMIT”错误。 所以我想在超过配额时将地理编码延迟几秒钟。 我有一个返回 promise 的函数 geocode()。当我超过配额时,我想递归调用自己。

这是我的无效代码:

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; 
}

更新 [已解决]

其实代码是对的。我有一个与延迟无关的 uncaughtException。使用 Q.all([..]).then().catch() 我找到了它

最佳答案

您的代码似乎工作正常。我在您的代码中看到的唯一问题是您使用的 latlng 超出了范围。但是您可能已经正确地编写了它,只是没有包含代码。我怀疑您可能错误地使用了这两个。这些应该是 geoData.latgeoData.lng 吗?

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

Plnkr

编辑

我认为您的问题可能与您的 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. */}
             )
     }
 }

使用 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...
  });
 }

或者您还可以使用 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 };
      });
     }

   });

关于javascript - 在 node.js 中返回一个延迟的嵌套 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35213796/

相关文章:

javascript - 将旧 javascript 转换为 jQuery 的工具

javascript - 如何在 node.js 中获取字符串的 sha1 哈希?

javascript - 在下一个请求之前等待 $http promise

javascript - Promise.all 与嵌套的 Promise.all

javascript - 如何在 react 中更改悬停时的图标颜色和样式?

javascript - 从 JavaScript 加载页面时调用 angularJS 函数

javascript - 垂直堆叠的动态网格布局

node.js - 使用 aws api 网关的 Wallet Pass 自动更新 Web 服务

node.js - 关于使用 NodeJS UI 服务器分离前端和后端的担忧

javascript - 在 JavaScript Promise 中正确使用 then