From my reading, async
and defer
aren’t meant to be used at the same time.
While your <script>
that loads the API from google is deferred, your <script>
with your code is not deferred. (If you remove async
and defer
your code works, but is theoretically slower.)
If you defer your code execution until the document is loaded (and the google api instantiated), then your code should work.
i.e., as sideroxylon alluded to,
<script> $(document).ready(function() { var service = new google.maps.places.PlacesService(document.getElementById('list')); ... }) </script>
or
<script> document.addEventListener('DOMContentLoaded', function() { var service = new google.maps.places.PlacesService(document.getElementById('list')); ... }) </script>
…I can not get this to work with async
, but I can with defer
. async
can be run at any time, even after DOMContentLoaded
. According to this, defer
does preserve order.
Here’s a good resource for execution order: https://www.kirupa.com/html5/running_your_code_at_the_right_time.htm
It shows that defer
happens just before the DOMContentLoaded
Event and async
scripts can execute at any time, although before the final load
Event.
As to why their example works, note that they add &callback=initMap
to the API URL, which presumably asks their code to call initMap()
after their code is initialized. That way you can chain your code (your initMap()
function) to their asynchronous load. e.g.,
<script> // define your callback before you invoke the API. function my_code() { var service = new google.maps.places.PlacesService(document.getElementById('list')); .... } </script> <script src="https://maps.googleapis.com/maps/api/js?key=APIKEY&libraries=places&callb