jQuery.each()内填充的邮编-距离键值对正常,循环结束后丢失距离值
问题原因
jQuery.promise()不支持第三方异步API等待
你给.each()调用.promise()只会等待jQuery内置的动画队列执行完毕,Google地图的getDistanceMatrix是独立的异步API请求,不属于jQuery队列管理范围。所以.done()触发时所有距离查询请求刚发出、还没有返回结果,distance_array自然没有距离值。- 变量作用域覆盖问题
.done(function(distance_array) {})的参数distance_array覆盖了你外层定义的存储距离的对象,这个参数实际是jQuery promise返回的集合对象,不是你自己定义的距离存储对象,因此打印结果不符合预期。
解决方案
用Promise.all包裹所有地图距离查询请求,等所有请求全部返回后再处理distance_array,修改后可运行代码如下:
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=API_KEY"> </script> jQuery( document ).ready( function() { jQuery( '#postal_search_btn' ).on( 'click', function(e) { e.preventDefault(); var distance_array = {}; var postalorigin = jQuery( '#postal_search' ).val(); var postals_string = jQuery( '#available_postals' ).attr( 'data-postals' ); var postals_array = postals_string.split( ',' ); // 将所有距离查询请求封装为Promise数组 var requestPromises = postals_array.map(function(nextpostal) { return new Promise(function(resolve) { var serviceDM = new google.maps.DistanceMatrixService(); serviceDM.getDistanceMatrix( { origins: [postalorigin], destinations: [nextpostal], travelMode: google.maps.TravelMode.DRIVING, avoidHighways: false, avoidTolls: false, }, function( response, status ) { if( status == google.maps.DistanceMatrixStatus.OK ) { distance_array[nextpostal] = response.rows[0].elements[0].distance['value']; } else { console.log(nextpostal + '距离查询失败'); } resolve(); // 无论成功失败都标记当前请求完成,避免中断整体流程 }); }); }); // 所有请求完成后再执行后续逻辑 Promise.all(requestPromises).then(function() { console.log(distance_array); // 此处直接写你已实现的排序、截取、AJAX查询逻辑即可 }); } ); } );
额外优化建议
- 若目的地邮编数量超过25个,建议拆分请求分批调用,避免触发Google Distance Matrix的单次请求配额限制
- 可增加
response.rows[0].elements[0].distance的判空逻辑,避免部分无路线的地址导致代码报错
内容的提问来源于stack exchange,提问作者Tony Djukic
相关产品推荐
相关产品推荐

