簡體   English   中英

為什么我的 Google Maps API 回調在前面的內聯腳本之前執行?

[英]Why is my Google Maps API callback executing before the preceding inline script?

<script src="/js/site.js?v=EtZhOXlkRte5HDRXpfS7rDy3ua0sbCvtNJUaIlNsSXw"></script>
<script>
    var init;
    $(function () {
        var adpSummaryListenerId;
        init = _initializeDirections;
        initializeAdpSummaryListener();

        function _initializeDirections() {
            console.log("test"); //we don't get here, sometimes
            var origin = {
                isGoogle: $("#origin-isgoogle").val(),
                coordinate: new google.maps.LatLng(@origin.Latitude, @origin.Longitude),
                address: "@origin.StreetAddress",
                marker: "@origin.MarkerName"
            }, destination = {
                isGoogle: $("#destination-isgoogle").val(),
                coordinate: new google.maps.LatLng(@destination.Latitude, @destination.Longitude),
                address: "@destination.StreetAddress",
                marker: "@destination.MarkerName"
            }, start = {
                value: origin.isGoogle ? origin.address : origin.coordinate,
                pos: origin.coordinate,
                marker: origin.marker
            }, end = {
                value: destination.isGoogle ? destination.address : destination.coordinate,
                pos: destination.coordinate,
                marker: destination.marker
            };

            console.log("Initializing directions");
            initializeDirections(start, end); //in site.js
        }

        function initializeAdpSummaryListener() {
            adpSummaryListenerId = window.setInterval(addNavigateButton, 500);
        }

        function addNavigateButton() {
            console.log("checking for .adp-summary");
            if ($(".adp-summary").length) {
                $(".adp-summary").append($("#start-navigation").html());
                clearInterval(adpSummaryListenerId);
            }
        }
    });
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=@(Model.GoogleMapsApiKey)&callback=init"></script>

我不明白為什么,盡管在內聯腳本之后引用了地圖腳本,但有時在 Google 嘗試調用它之前不會實例化 Google Maps API 回調init

這是我得到的錯誤:

Uncaught (in promise)
ld {message: "init is not a function", name: "InvalidValueError", stack: "Error at new ld (https://maps.googleapis.com/.......&callback=init:141:124"}

我以前將回調名稱作為initializeMap作為在 site.js 中聲明的引用(但仍然在內聯腳本中在這里初始化),但為了簡潔和隔離,將它移到這里,希望我能夠找出問題所在。 但同樣的問題仍然存在。

知道async指示 api 在解析和評估可用時並行獲取,但它不應該在內聯腳本之前可用,對嗎?

我也明白defer表示在解析文檔之后才會執行 api,所以它仍然不應該可用。

我確實看到了這個關於defer

此屬性允許消除阻止解析器的 JavaScript,瀏覽器在繼續解析之前必須加載和評估腳本。 在這種情況下,異步具有類似的效果。

但是defer仍然不應該阻止內聯腳本首先執行,因為如果在內聯<script>標簽上使用該屬性,它只會使 JavaScript不必被解析器阻塞

所以我不知所措。

您上面的內聯腳本確實首先運行,但是$(function () {是一個 jQuery 構造,它只在文檔准備好后才在內部運行回調。看起來 Google 腳本首先運行。

如果您為 Google 的腳本提供defer屬性,它只會在 DOM 構建完成后運行,而$(function () {將是不必要的。因此,只需將所有內容移出$(function () {以便init將在頂層,並在 Google 的腳本加載時由 Google 調用:

<script>
function init() {
            var origin = {
                isGoogle: $("#origin-isgoogle").val(),
                coordinate: new google.maps.LatLng(@origin.Latitude, @origin.Longitude),
                address: "@origin.StreetAddress",
                marker: "@origin.MarkerName"
            }, destination = 
            // etc

請注意,雖然您可以使用asyncdefer ,但您不應同時使用兩者。 要等到 DOM 加載完畢,請使用defer而不是async

除了分配給變量之外,您上面的內聯腳本還有件事是調用initializeAdpSummaryListener 你可以把它放在$(function () {如果你需要確保在運行之前加載 DOM:

$(initializeAdpSummaryListener);

另一個控制流程可能更容易理解的選項是將所有內容放在 Google 在加載時調用的命名函數中(給定defer屬性,該函數僅在頁面加載時發生)。

暫無
暫無

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

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