javascript - 如何处理多个 Promise 链中的 Google Maps API V3 事件?

标签 javascript jquery google-maps promise deferred

我有一个设置,在页面加载时,如果 URL 中有查询值(?st=CA&s=park..."等),则 javascript 使用 fetch 来获取其中包含一些数据的 JSON 文件。

在获取的返回 Promise 上,JSON 数据随后被传递给其他 3 个 Promise,其中一个创建一些 html,一个创建一些选择字段值,最后一个创建一个 Google map 。在这一切之后,有一个全屏覆盖层淡出,并且页面的不同元素(gmap、select、html)使用 Motion UI 系列动画进行动画处理。

我遇到的问题是如何让 Promise.all([]).then() 知道 google “tilesloaded”事件已触发。原因是,如果在动画发生时 map 仍在渲染,则会出现相当多的卡顿,动画不会那么流畅。

基本代码/逻辑如下所示,

$(document).ready(function() {

    var query = bsky_GetQueryFromURL(); // gets ?cat=23,43&state=CA
    var data_P = bsky_GetCampaignProjects(); // gets JSON file with fetch

    if (! $.isEmptyObject(query)) {

        data_P
            .then(data => bsky_FilterData(data, query)) // filters data by query
            .then(data => bsky_MakeQueryView(data))
            .then(values => {
                bksy_Animation_QueryView_IN();
            });

    } else {

        bsky_MakeNoQueryView();

    }
});

function bsky_MakeQueryView(data) {
    var gMap_P = bsky_setupGoogleMap(data);
    var pHTML_P = bsky_setupProjectsList(data);
    var selects_P = bsky_setupRefineBySelects(data)

    return Promise.all([gMap_P, pHTML_P, selects_P]);
}

我希望能够在运行 animate in 函数之前知道 Google map 事件是否完成,

google.maps.event.addListener(map, "tilesloaded", function() { });

有没有办法通过延迟或 promise 来做到这一点?

function bsky_setupGoogleMap(subset) {
    var options = {
        scrollwheel: false,
        //navigationControl: false,
        mapTypeControl: false,
        //scaleControl: false,
        //draggable: false,
        zoom: 5,
        center: new google.maps.LatLng(39.8333333,-98.585522),
        mapTypeId: google.maps.MapTypeId.TERRAIN
    }

    var map = new google.maps.Map(document.getElementById('map'), options);
    var bounds = new google.maps.LatLngBounds();
    var markerImage = '';

    $(subset).each(function(k,v) {

        if (v.geo.national == 0) {
            var geo = v.geo.gmap;

            if (geo.hasOwnProperty('lat') && geo.hasOwnProperty('lng')) {
                var lat = parseInt(geo.lat);
                var lng = parseInt(geo.lng);
                var marker = new google.maps.Marker({
                    position: {lat: lat, lng: lng},
                    map: map,
                    title:v.project.title,
                    //icon: markerImage
                });
                var infowindow = new google.maps.InfoWindow({
                    content: bsky_Template_GMapInfoWindow(v),
                    maxWidth: 260
                });

                marker.addListener('click', function() {
                    infowindow.open(map, marker);
                    var iw_container = $(".gm-style-iw").parent();
                    iw_container.stop().hide();
                    iw_container.fadeIn(1000);
                });

                google.maps.event.addListener(map, 'click', function() {
                    infowindow.close();
                });

                google.maps.event.addListener(infowindow, 'domready', function() {

                    var iwOuter = $('.gm-style-iw');
                    var iwBackground = iwOuter.prev();

                    iwOuter.parent().parent().css({left: '135px'});
                    iwBackground.children(':nth-child(1)').attr('style', function(i,s){ return s + 'left: 10px !important;'});
                    iwBackground.children(':nth-child(3)').attr('style', function(i,s){ return s + 'left: 10px !important;'});

                });

                bounds.extend(marker.getPosition());
            }
        }
    });

    map.fitBounds(bounds);

    var listener = google.maps.event.addListener(map, "idle", function() { 
        if (map.getZoom() > 9) map.setZoom(11); 
            google.maps.event.removeListener(listener); 
    });

    return;
}

也许我有一个答案 - 比我想象的更容易?

    function bsky_setupGoogleMaps(data) {
    return new Promise(function(resolve, reject) {
     // ... all the google map code from above
     // then add this and resolve
        google.maps.event.addListener(map, "tilesloaded", function() { 
            resolve('tilesloaded');
        });

    });
}

最佳答案

function bsky_setupGoogleMaps(data) {
    return new Promise(function(resolve, reject) {
        // ... all the google map code from above
        google.maps.event.addListener(map, "tilesloaded", resolve);
    });
}

关于javascript - 如何处理多个 Promise 链中的 Google Maps API V3 事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37241073/

相关文章:

javascript - 如何用取决于被替换位的内容替换字符串的一部分?

javascript - 运行 npmserve 时收到错误消息模块构建失败(来自 ./node_modules/sass-loader/dist/cjs.js)

iphone - 在非英语语言的 iPhone 上使用 Google map 寻找方向

r - ggmap 扩展缩放或边界

javascript - 为什么在没有 new 关键字的情况下声明为函数的变量是未定义的?

jquery - css 已更改 - 插入的元素不可见

jquery - Internet Explorer 8 和 jquery addEventListener

javascript - 开窗器操纵;向父窗口中的元素添加文本

javascript - 将字符串数组值转换为数组对象

javascript - 从缓存数组中检索预加载的图像