问题的引出:在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之站立会议8 /2015-5-21

    今天我们把聊天界面做了优化和改进,主要实现了聊天的功能.显示了正在进行通信的成员列表,和当前状态,是否连通和正常通信,大体完成了预期的目标. 燃尽图8

  2. Leetcode题库——1.两数之和

    @author: ZZQ @software: PyCharm @file: addTwoNumbers.py @time: 2018/9/18 10:35 要求:给定两个非空链表来表示两个非负整数. ...

  3. ubuntu16.04安装cuda8.0试错锦集

    ubuntu16.04安装cuda8.0试错锦集 参考文献: [http://www.jianshu.com/p/35c7fde85968] [http://blog.csdn.net/sinat_1 ...

  4. fragment的学习

    这个讲的不错 http://blog.csdn.net/lmj623565791/article/details/37992017  Fragment与Activity交互的几种方式(二,使用Bund ...

  5. Software Defined Networking(Week 1)

    前言 课程名称:软件定义网络 课程地址 Coursera上新的一期还没开课,所以是YouTube. Instructor:Nick Feamster Get Started 对于本次课程,主要的新内容 ...

  6. Intellij IDEA中file size exceeds configured limit解决

    把Hadoop源码导入IDEA中后,其中有个ClientNamenodeProtocolProtos文件代码高达82997行,IDEA直接就不把它当java类看了,报file size exceeds ...

  7. [2017BUAA软工]第1次个人作业

    软工第1次个人作业 一.快速看完整部教材,列出你不懂的5-10个问题,发布在你的个人博客上. 1.文中提到"积累问题领域的知识和经验(例如:对医疗或金融行业的了解)."然而我们如何 ...

  8. 第八周PSP&进度条

    团队项目PSP 一.表格:     C类型 C内容 S开始时间 E结束时间 I时间间隔 T净时间(mins) 预计花费时间(mins) 讨论 讨论各个模块页面设计 9:30 12:30 站立会议 分配 ...

  9. 每日站立会议——敏捷流程scrum实践

    每日站立会议是敏捷流程scrum中的很重要的一个制度之一. 功能:     1.快速同步进展,让项目组内部的员工互相了解彼此的进展,从而了解本项目的整体进展.      2.给每个人一种精神压力,信守 ...

  10. #Leetcode# 692. Top K Frequent Words

    https://leetcode.com/problems/top-k-frequent-words/ Given a non-empty list of words, return the k mo ...