How can I wait for an asynchronously created object to be completely available before invoking a callback?

我只是一个虾纸丫 提交于 2019-12-23 09:29:36

问题


I'm trying to create a function that will create a new marker. I need to be able to process some of the properties of the new marker in the callback. The problem is that marker is immediately created and can be used to invoke the callback, but some properties are not yet available.

If I wait two seconds before trying to access the properties, it works just fine - this leads me to believe that the object is still asynchronously generating itself after being created.

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Simple markers</title>
    <style>
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #map {
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <script>

function initMap() {
  var latLng = new google.maps.LatLng(-25.363, 131.044);

  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: latLng
  });

  function placeMarker(map, latLng, callback, callback2){
        var marker = new google.maps.Marker({
            position: latLng,
            map: map });

        callback(marker);
        callback2(marker);
    }

    placeMarker(map, latLng, function(marker){
        setTimeout( function(){ 
            console.log(marker.Xg.Oa)
        }, 2000);
    }, function(marker){
        console.log(marker.Xg.Oa);
    });

}
    </script>
    <script async defer
        src="https://maps.googleapis.com/maps/api/js?signed_in=true&callback=initMap"></script>
  </body>
</html>

In this example the callback:

setTimeout( function(){ 
    console.log(marker.Xg.Oa)
}, 2000);

yields the correct response. But the callback that doesn't wait shows an undefined error:

function(marker){
    console.log(marker.Xg.Oa);
}

I'm using a the Google Maps Javascript API library here, and messing with the google.maps stuff isn't an option for obvious reasons. I want to pass the entire object to the callback but I need to ensure that the latLng information (marker.Xg.Oa) exists before invoking it. How can I ensure that it's there before invoking the callback?


回答1:


NB: I have NOT tested this but something along these lines...

var map = //...
var latLng = //...

function placeMarker(map, latLng, callback){

    return new Promise(function(resolve, reject)(){

        getMarker().then(function(marker){
            //The marker is immediately available
            console.log(marker); //me {__gm: Object, ... }

            //Try to get the value we need
            console.log(marker.Xg.Oa); //Uncaught TypeError: Cannot read property 'Oa' of undefined

            //wait two seconds and try again
            setTimeout(function(){ console.log(marker.Xg.Oa) }, 2000); // L {} (this is the expected output)

            while(!marker.Xg.Oa){ //Uncaught TypeError: Cannot read property 'Oa' of undefined
                callback(marker.Xg.Oa);
            }

            resolve(true);
        });
    });

}

function getMarker()
{
    return new Promise(function(resolve, reject){
        var marker = new google.maps.Marker({
            position: latLng,
            map: map 
        });

        resolve(marker);
    });
}


来源:https://stackoverflow.com/questions/33245495/how-can-i-wait-for-an-asynchronously-created-object-to-be-completely-available-b

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!