Геокод не был успешным по следующей причине: OVER_QUERY_LIMIT [дублировать]

Еще один подход к возврату значения из асинхронной функции - передать объект, который сохранит результат от асинхронной функции.

Вот пример того же:

var async = require("async");

// This wires up result back to the caller
var result = {};
var asyncTasks = [];
asyncTasks.push(function(_callback){
    // some asynchronous operation
    $.ajax({
        url: '...',
        success: function(response) {
            result.response = response;
            _callback();
        }
    });
});

async.parallel(asyncTasks, function(){
    // result is available after performing asynchronous operation
    console.log(result)
    console.log('Done');
});

Я использую объект result для хранения значения во время асинхронной операции. Это позволяет получить результат даже после асинхронного задания.

Я использую этот подход много. Мне было бы интересно узнать, насколько хорошо этот подход работает, когда задействован результат обратно через последовательные модули.

36
задан Artjom B. 14 November 2014 в 13:02
поделиться

5 ответов

Ничто не похоже на эти две строки в учебнике Майка Уильямса:

    wait = true;
    setTimeout("wait = true", 2000);

Вот порт версии 3:

http://acleach.me.uk /gmaps/v3/plotaddresses.htm

Соответствующим битом кода является

  // ====== Geocoding ======
  function getAddress(search, next) {
    geo.geocode({address:search}, function (results,status)
      { 
        // If that was successful
        if (status == google.maps.GeocoderStatus.OK) {
          // Lets assume that the first marker is the one we want
          var p = results[0].geometry.location;
          var lat=p.lat();
          var lng=p.lng();
          // Output the data
            var msg = 'address="' + search + '" lat=' +lat+ ' lng=' +lng+ '(delay='+delay+'ms)<br>';
            document.getElementById("messages").innerHTML += msg;
          // Create a marker
          createMarker(search,lat,lng);
        }
        // ====== Decode the error status ======
        else {
          // === if we were sending the requests to fast, try this one again and increase the delay
          if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
            nextAddress--;
            delay++;
          } else {
            var reason="Code "+status;
            var msg = 'address="' + search + '" error=' +reason+ '(delay='+delay+'ms)<br>';
            document.getElementById("messages").innerHTML += msg;
          }   
        }
        next();
      }
    );
  }
38
ответ дан Andrew Leach 28 August 2018 в 13:26
поделиться

Вы используете неправильный путь setTimeout . Сигналом функции (одной из) является setTimeout(callback, delay). Таким образом, вы можете легко указать, какой код следует запускать после какой задержки.

var codeAddress = (function() {
    var index = 0;
    var delay = 100;

    function GeocodeCallback(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            map.setCenter(results[0].geometry.location);
            new google.maps.Marker({ map: map, position: results[0].geometry.location, animation: google.maps.Animation.DROP });
            console.log(results);
        }
        else alert("Geocode was not successful for the following reason: " + status);
    };

    return function(vPostCode) {
        if (geocoder) setTimeout(geocoder.geocode.bind(geocoder, { 'address': "'" + vPostCode + "'"}, GeocodeCallback), index*delay);
        index++;
    };
})();

Таким образом, каждый вызов codeAddress() приведет к тому, что geocoder.geocode() будет вызван через 100 мс позже после предыдущего вызова.

Я также добавил анимацию в маркер, чтобы у вас был приятный эффект анимации с добавлением маркеров для сопоставления один за другим. Я не уверен, каков текущий лимит Google, поэтому вам может потребоваться увеличить значение переменной delay.

Кроме того, если вы каждый раз геокодируете одни и те же адреса, вместо этого вы должны сохранить результаты геокодирования на свой db, а в следующий раз просто используйте их (чтобы вы сэкономили некоторый трафик, и ваше приложение будет немного бит быстрее)

0
ответ дан Buksy 28 August 2018 в 13:26
поделиться
9
ответ дан geocodezip 28 August 2018 в 13:26
поделиться

Здесь я загрузил 2200 маркеров. Для добавления 2200 местоположений требуется около 1 минуты. https://jsfiddle.net/suchg/qm1pqunz/11/

//function to get random element from an array
    (function($) {
        $.rand = function(arg) {
            if ($.isArray(arg)) {
                return arg[$.rand(arg.length)];
            } else if (typeof arg === "number") {
                return Math.floor(Math.random() * arg);
            } else {
                return 4;  // chosen by fair dice roll
            }
        };
    })(jQuery);

//start code on document ready
$(document).ready(function () {
    var map;
    var elevator;
    var myOptions = {
        zoom: 0,
        center: new google.maps.LatLng(35.392738, -100.019531), 
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map($('#map_canvas')[0], myOptions);

    //get place from inputfile.js
    var placesObject = place;
    errorArray = [];

  //will fire 20 ajax request at a time and other will keep in queue
    var queuCounter = 0, setLimit = 20; 

  //keep count of added markers and update at top
  totalAddedMarkers = 0;

  //make an array of geocode keys to avoid the overlimit error
    var geoCodKeys = [
                    'AIzaSyCF82XXUtT0vzMTcEPpTXvKQPr1keMNr_4',
                    'AIzaSyAYPw6oFHktAMhQqp34PptnkDEdmXwC3s0',
                    'AIzaSyAwd0OLvubYtKkEWwMe4Fe0DQpauX0pzlk',
                    'AIzaSyDF3F09RkYcibDuTFaINrWFBOG7ilCsVL0',
                    'AIzaSyC1dyD2kzPmZPmM4-oGYnIH_0x--0hVSY8'                   
                ];

  //funciton to add marker
    var addMarkers = function(address, queKey){
        var key = jQuery.rand(geoCodKeys);
        var url = 'https://maps.googleapis.com/maps/api/geocode/json?key='+key+'&address='+address+'&sensor=false';

        var qyName = '';
        if( queKey ) {
            qyName = queKey;
        } else {
            qyName = 'MyQueue'+queuCounter;
        }

        $.ajaxq (qyName, {
            url: url,
            dataType: 'json'
        }).done(function( data ) {
                    var address = getParameterByName('address', this.url);
                    var index = errorArray.indexOf(address);
                    try{
                        var p = data.results[0].geometry.location;
                        var latlng = new google.maps.LatLng(p.lat, p.lng);
                        new google.maps.Marker({
                            position: latlng,
                            map: map
                        });
                        totalAddedMarkers ++;

            //update adde marker count
                        $("#totalAddedMarker").text(totalAddedMarkers);
                        if (index > -1) {
                            errorArray.splice(index, 1);
                        }
                    }catch(e){
                        if(data.status = 'ZERO_RESULTS')
                            return false;

            //on error call add marker function for same address
            //and keep in Error ajax queue
                        addMarkers( address, 'Errror' );
                        if (index == -1) {
                            errorArray.push( address );
                        }
                    }
        });

    //mentain ajax queue set
        queuCounter++;
        if( queuCounter == setLimit ){
            queuCounter = 0;
        }
    }

  //function get url parameter from url string
    getParameterByName = function ( name,href )
    {
      name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
      var regexS = "[\\?&]"+name+"=([^&#]*)";
      var regex = new RegExp( regexS );
      var results = regex.exec( href );
      if( results == null )
        return "";
      else
        return decodeURIComponent(results[1].replace(/\+/g, " "));
    }

  //call add marker function for each address mention in inputfile.js
    for (var x = 0; x < placesObject.length; x++) {
        var address = placesObject[x]['City'] + ', ' + placesObject[x]['State'];
        addMarkers(address);
    }
});
4
ответ дан Matheno 28 August 2018 в 13:26
поделиться

Использование «setInterval» & amp; «clearInterval» устраняет проблему:

function drawMarkers(map, markers) {
    var _this = this,
        geocoder = new google.maps.Geocoder(),
        geocode_filetrs;

    _this.key = 0;

    _this.interval = setInterval(function() {
        _this.markerData = markers[_this.key];

        geocoder.geocode({ address: _this.markerData.address }, yourCallback(_this.markerData));

        _this.key++;

        if ( ! markers[_this.key]) {
            clearInterval(_this.interval);
        }

    }, 300);
}
3
ответ дан Ronen 28 August 2018 в 13:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: