簡體   English   中英

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

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

我在我的代碼中使用Google地理編碼。 我必須對大約50個地方進行地理編碼,但Google不允許同時對這么多地方進行地理編碼,從而產生“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; 
}

更新[已解決]

實際上代碼是對的。 我有一個與延遲無關的未被捕獲的異常。 使用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 };
      });
     }

   });

代碼看起來不錯。 也許geocoder.geocode或其他東西犯了錯誤。 嘗試設置:

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

要么:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM