问题的引出:在js中使用异步调用时,有可能会出现在异步的回调函数中设置调用之外的变量值,但在异步调用完成后去使用变量,却发现这些变量值并没有被成功设置的情况。如: google map中的地理编码,地理编码是将地址(如“1600 Amphitheatre Parkway, Mountain View, CA”)转换为地理坐标(如纬度 37.423021 和经度 -122.083739)的过程,您可以根据该地理坐标放置标记或定位地图。这个服务是异步调用,他使用geocoder进行服务查询,在查询过程中会使用返回状态码,当返回成功后我们设置其中的经度和纬度,并在以后的过程中使用这些经度和纬度,当后面的程序使用这些经度和纬度的时候发现这些经度和纬度并没有被正确地设置。

例如:

 <!DOCTYPE html>
<html>
<head>
<title>Geocoding Test</title>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
6 <script type="text/javascript" src="geocode.js"></script>
7 </head>
8 <body>
9 <div id="panel"> <input id="address" type="text" value=""> <input type="button" value="Change" onclick="codeAddress()"> </div> <div id="map-canvas"></div> </body> </html>
 var valLat = 0, valLng = 0;

 function codeAddress() {
var geocoder = new google.maps.Geocoder();
var address = document.getElementById('address').value; geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
valLat = results[0].geometry.location.lat();
valLng = results[0].geometry.location.lng();
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
alert("valLat: " + valLat + ", valLng: " + valLng);
}

整个页面有一个文本输入框和一个按扭,在文本框中输入地址“中国”,然后点击“Change”按扭

预期结果:显示出”中国“的经纬度信息

实际结果:显示的经纬度均为初始值0

分析原因:地理编码是异步服务,因此当执行geocode服务后就会继续执行后面处理经纬度的代码,此时的经纬度还没有被设置而是初始值

改进方法:将显示经纬度的代码放入地理编码的回调函数中,此时就会显示出正确的”中国“的经纬度

 var valLat = 0, valLng = 0;

 function codeAddress() {
var geocoder = new google.maps.Geocoder();
var address = document.getElementById('address').value; geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
valLat = results[0].geometry.location.lat();
valLng = results[0].geometry.location.lng();
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
alert("valLat: " + valLat + ", valLng: " + valLng);
});
//alert("valLat: " + valLat + ", valLng: " + valLng);
}

新的问题:虽然这样可以解决异步调用显示不正确的问题,但是这样涉及到破坏封装,并造成不易于维护

改进方法:将涉及到经纬度处理的代码段使用一个函数进行调用

 var valLat = 0, valLng = 0;
var count = 1; //function codeAddress() {
function codeAddress(callback) {
var geocoder = new google.maps.Geocoder();
var address = document.getElementById('address').value;
alert(address);
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
valLat = results[0].geometry.location.lat();
valLng = results[0].geometry.location.lng();
callback(valLat, valLng);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
//alert("valLat: " + valLat + ", valLng: " + valLng);
//alert("valLat: " + valLat + ", valLng: " + valLng + ", count: " + count); });
//alert("valLat: " + valLat + ", valLng: " + valLng);
}

JS中的异步与回调的更多相关文章

  1. JS中的异步以及事件轮询机制

    一.JS为何是单线程的? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊.(在JAVA和c#中的异步 ...

  2. js中的异步与同步,解决由异步引起的问题

    之前在项目中遇到过好多次因为异步引起的变量没有值,所以意识到了认识js中同步与异步机制的重要性 在单线程的js中,异步代码会被放入一个事件队列,等到所有其他代码执行后再执行,而不会阻塞线程. 下面是j ...

  3. JS中的异步

    Hello,日常更新的我“浪”回来了!!! JS中有三座高山:异步和单线程.作用域和闭包.原型原型链 今天“浪”的主题是JS中的异步和单线程的问题. 主要从这三个方面入手 一.什么是异步(与同步作比较 ...

  4. js中的异步[Important]

    js作为前端最主流的语言,主要处理页面显示变化(mutation)和异步(asynchronicity), js语言的基本要素和使用惯例的演化大都围绕着这两大主题,两者均值得总结和思考的主题, 这里先 ...

  5. 互联网我来了 -- 2. js中&quot;异步/堵塞&quot;等概念的简析

    一.什么是"异步非堵塞式"? 这个名字听起来非常恶心难懂,但假设以 买内裤 这件事情来比喻运行程序的话就非常easy理解"异步非堵塞式"的涵义了. 比如你是一个 ...

  6. 咱们来聊聊JS中的异步,以及如何异步,菜鸟版

    为什么需要异步?why?来看一段代码. 问题1: for(var i=0;i<100000;i++){ } alert('hello world!!!'); 这段代码的意思是执行100...次后 ...

  7. js同步、异步、回调的执行顺序以及闭包的理解

    首先,记住同步第一.异步第二.回调最末的口诀 公式表达:同步=>异步=>回调 看一道经典的面试题: for (var i = 0; i < 5; i++) { setTimeout( ...

  8. 【第三周读书笔记】浅谈node.js中的异步回调和用js-xlsx操作Excel表格

    在初步学习了node.js之后,我发现他的时序问题我一直都很模糊不清,所以我专门学习了一下这一块. 首先我们来形象地理解一下进程和线程: 进程:CPU执行任务的模块.线程:模块中的最小单元. 例如:c ...

  9. promise 的基本概念 和如何解决js中的异步编程问题 对 promis 的 then all ctch 的分析 和 await async 的理解

    * promise承诺 * 解决js中异步编程的问题 * * 异步-同步 * 阻塞-无阻塞 * * 同步和异步的区别? 异步;同步 指的是被请求者 解析:被请求者(该事情的处理者)在处理完事情的时候的 ...

随机推荐

  1. 冲刺One之站立会议5 /2015-5-18

    2015-5-18 服务器部分大体已经完工,现在我们主要是在把登陆界面和服务器组装起来,这个过程是很让人头痛的,以为其中涉及到了很多网络协议.网络编程的知识,由于之前我们没有接触过所以实现起来会觉得很 ...

  2. Task 6.2冲刺会议十 /2015-5-23

    今天是第一个冲刺阶段的最后一天,主要把做出来的程序进行了初步的测试,在一台笔记本上运行程序,摄像头可以工作也能听到声音和麦克多的运转也还可以,两台计算机同时在一个局域网中通信的时候也可以实现.不过后续 ...

  3. 微服务注册与发现 —— eureka

    基础概念 在微服务系统中,服务的注册和发现是第一步,常用的有: Eureka:https://github.com/Netflix/eureka Zookeeper:https://zookeeper ...

  4. Java join & yield

    Thread.yield()方法作用是:暂停当前正在执行的线程对象,并执行其他线程. yield()应该做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会.因此,使用yie ...

  5. syntax error:unexpected end of file

    将window上编辑的xxy1.sh脚本上传到linux上,并执行的时候提示 xxy1.sh: line 17: syntax error: unexpected end of file 但是通过ca ...

  6. node入门学习(一)

    一.安装node.js 方式很多npm,git等,新手建议从官网上直接去下载node的安装包.一键安装. 二.创建一个web服务器. const http = require('http'); htt ...

  7. error_reporting 报错

    <?php // 关闭所有PHP错误报告 error_reporting(0); // 报告简单的运行错误 error_reporting(E_ERROR | E_WARNING | E_PAR ...

  8. WDS迁移注意事项

    先说背景:公司使用WDS来部署操作系统,目前DHCP和WDS都安装在同一台服务器上,但是此服务器已过保,所以筹划迁移,将WDS和DHCP分别迁移到两台服务器上.迁移计划是保持WDS暂时不动,DHCP先 ...

  9. @Primary 注解引出的问题

    @Primary 注解 刚看到这个,还以为是持久层的注解呢,以为和@Id差不多,一查才知道,这两个风马牛不相及,反倒和@Qualifier以及@Resource有点像了,但是相比而言,后面两个更加的灵 ...

  10. input select & input unselect

    input select & input unselect input select https://developer.mozilla.org/en-US/docs/Web/API/HTML ...