异步操作应该是以前学习 ajax 时才被明确提及,就目前的理解,同步就是同一时间只能做一件事,如果使用 ajax同步模式,则代码会卡在 xhr.send() 这里,只有请求响应的过程全部完成了才会执行下面的代码,而异步操作的话代码的执行不会等待,会直接一溜烟地从上到下执行完

js 中的异步操作:

❶ 定时器

❷ 事件绑定

❸ ajax异步模式

❹ 回调函数

如何获取一个函数中异步操作的结果,例如调用函数 fn() 得到内部变量 data 的值

function fn() {
  setTimeout(function () {
  var data = 'Hi'
},1000)
  console.log(data)
}
fn()

由于定时器 1 秒后才执行,但代码早已执行到了 console,所以输出结果为 data is not defined

function fn() {
setTimeout(function () {
var data = 'Hi'
return data
},1000)
}
console.log(fn())

fn 函数没有返回值,所以输出结果为 undefined

return 是定时器里的那个 function 进行 return 的,与 fn 无关

var data = '^_^'
function fn() {
setTimeout(function () {
data = 'Hi'
},1000)
return data
}
console.log(fn())

定时器是异步的,所以代码不等待,会直接执行到 return,赋值操作没有执行,所以结果为 ^_^

正确方式

如果需要获取一个函数中异步操作的结果,则必须通过回调函数来获取

function fn(callback) {
//传入一个函数,就相当于在这创建了一个叫callback的函数
//var callback = function (data) { console.log(data) }
setTimeout(function () {
var data = 'Hi'
callback(data)

},1000)
}
fn(function (data) {
console.log(data)
})

关键的一步是在定时器内调用 callback ,前面的情况之所以拿不到数据是因为,data 变量在定时器内定义,函数不等定时器里的 function 执行就立马想拿到数据,就是人家产品都没做好你就来提货,这显示是不行的

现在 callback 在定时器的 function 里执行,并且是在 data 变量初始化后才执行,就保证能拿到数据,即便定时器是10秒甚至一分钟都没关系,反正都是等 data 初始化后才执行 callback

还有种方式可以获取 data 的值,就是将其定义为全局变量,定时器一秒后执行,那就两秒后进行调用,但此方式没有意思

var data
function fn() {
setTimeout(function () {
data = 'Hi'
},1000)
}
fn() setTimeout(function () {
console.log(data) //两秒后结果为Hi,若将2000改为0,结果为undefined
},2000)

封装异步API

模拟 jq 的 ajax.get() 方法,封装原生 ajax

var xhr = new XMLHttpRequest()
  xhr.open('get', './db.json')
  xhr.send()
  xhr.onload = function () {
  console.log(xhr.responseText)
}

自定义 get() 方法,获取 ajax 响应数据

function get(url,callback) {
  var xhr = new XMLHttpRequest()
xhr.open('get', url)
xhr.send()
xhr.onload = function () {
  callback(xhr.responseText)
}
}
get('./db.json',function (data) {
console.log(data)
})

还有个小栗子,Node 封装一个写入文件的小模块,在 app.js 中调用 writeFile.js 的方法,将数据写入 db.json 中

db.json 文件里有一个对象,里面是 json 数组,存储着两个学生的信息

writeFile.js

var fs = require('fs')

exports.add = function (stuObj,callback) {
//如果直接写入则会覆盖db.json原有内容,要先读取出来
fs.readFile('./db.json','utf-8',function (err,data) {
if(err){
return callback(err) //读取失败,return为了结束readFile
} //文件中数据不是对象,所以只能先转为对象,再可以添加
var arr = JSON.parse(data).Student
stuObj.id = arr[arr.length - 1].id + 1 //设置id
arr.push(stuObj) //把对象转为字符串才能写入到db.json
var fileData = JSON.stringify({Student:arr}) fs.writeFile('./db.json',fileData,function (err) {
if(err){
return callback(err)
}
callback(null) //写入成功,不需要返回err对象
})
})
}

app.js

//引包,得到writeFile.js导出的对象,此对象有个add属性,其值为一个方法
var exportsObj = require('./writeFile') //将data写入到db.json.数据应该由表单提交而来,但这里只是为了熟悉封装思路
var data = {"name":"Aaron","sex":1} //文件的读写的异步,所以需要回调函数来获取数据
exportsObj.add(data,function (err) {
if(err){
console.log(err)
}
})

写入成功

有点蒙圈的时候可以想,回调函数是用来存储数据的,存储的数据在哪里被使用了,可能有助于回想整个过程

获取异步API数据的更多相关文章

  1. 解决GJson 获取web api数据出现Not a JsonObject问题

    服务器端web api服务采用asp.net web api编写,对请求的数据序列化成Json格式的字符串进行传递. 客户端采用Java进行接收处理,处理采用GJson进行解析,出现Not a Jso ...

  2. 通过Jquery异步获取股票实时数据

    最近朋友让我帮他做个异步获取数据的程序,暂时服务器什么都没有,所以我就想先拿股票数据打个框架,方便后续开发和移植等事情 代码如下: <!-- 说明:股票看盘 作者:黑桃A 时间:2014-04- ...

  3. 传递多个参数并获取Web API的数据

    近段时间学习Web Api觉得非常有意思.默认的路由情况之下,获取数据时,它不必指定Action操作名. 还有另外感想,就是自从学习asp.net MVC之后,加上jQuery,让Insus.NET已 ...

  4. react生命周期获取异步数据

    当react组件需要获取异步数据的时候,建议在ComponentDidMount周期里执行获取动作, 如果非异步数据,可以在ComponentWillMount获取 因为ComponentWillMo ...

  5. 【vue】获取异步加载后的数据

    异步请求的数据,对它做一些处理,需要怎么做呢?? axios 异步请求数据,得到返回的数据, 赋值给变量 info .如果要对 info 的数据做一些处理后再赋值给 hobby ,直接在 axios ...

  6. Code First系列之视图,存储过程和异步API

    返回<8天掌握EF的Code First开发>总目录 本篇目录 视图View 存储过程 使用存储过程CRUD 异步API 本章小结 自我测试 本系列的源码本人已托管于coding上:点击查 ...

  7. 使用腾讯开发平台获取QQ用户数据资料

    <今天是七夕:祝大家七夕嗨皮,前可么么哒,后可啪啪啪> Tips:本篇博客将教你如何使用腾讯开发平台获取QQ用户资料 ----------------------------------- ...

  8. 8天掌握EF的Code First开发系列之5 视图、存储过程和异步API

    本文出自8天掌握EF的Code First开发系列,经过自己的实践整理出来. 本篇目录 视图View 存储过程 异步API 本章小结 咱们接着上一篇继续深入学习,这一篇说说Entity Framewo ...

  9. 串行通讯之.NET SerialPort异步写数据

    目录 第1章说明    2 1 为什么需要异步写数据?    2 2 异步写数据的代码    2 3 源代码    4 第1章说明 1 为什么需要异步写数据? 如下图所示,以波特率300打开一个串口. ...

随机推荐

  1. 【优秀的Sketch插件】PaintCode for Sketch for Mac 1.1

    [简介] PaintCode for Sketch 是一款结合了PaintCode和Sketch两款软件强大功能的插件,今天和大家分享最新的1.1版本,支持Sketch 40+版本,这个插件能够让你的 ...

  2. go 实现用户特权判断的例子

    需求:实现用户特权,可以满足下面1个或多个条件 红名 达人 vip会员 vip超级会员 蓝钻用户 红钻用户 1.实现方法一:可以根据数据库字段,每个特权用一个字段,进行判断缺点:每增加一个特权,要进行 ...

  3. 缓存淘汰策略之LRU

    LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”. 1. 新数据插入到链表头部: ...

  4. Linux系统IO分析工具之iotstat常用参数介绍

    Linux系统IO分析工具之iotstat常用参数介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 1>.安装iostat [root@flume115 ~]# yum - ...

  5. java语音转文字

    用到的百度提供的api 需要把wav音频文件转成16k的频率,必须转,不转百度api解析不出来.显示音频文件不清晰错误.想要转化还必须要有ffmpeg程序,这个自己百度去下载.然后拿转好的文件扔到百度 ...

  6. linux部署Web项目总结

    本文用的是CentOS7系统,不是虚拟机. 1.什么是Xshell? xshell连接上linux之后,就等同于linux本身的终端命令窗口. xshell不是必需品,但是它能更好的辅助我们学习lin ...

  7. mysq存储金额的数值类型选择

    在之前得项目中用到了double,计算之后有很长得小数位,需要用算法去除,非常麻烦,以后推荐使用:decimal 这个是专门处理金额值的,Java 类型对应BigDecimal

  8. flask请求异步执行(转载)

    Flask默认是不支持非阻塞IO的,表现为: 当 请求1未完成之前,请求2是需要等待处理状态,效率非常低. 在flask中非阻塞实现可以由2种: 启用flask多线程机制 # Flask from f ...

  9. python练习实例2--------构造数据类型

    有如下数据类型 cars = ['鲁A32444', '鲁B12333', '京B8989M', '黑C49678', '黑C46555', '沪B25041', '黑C34567'] locatio ...

  10. 配置tomcat限制指定IP地址访问后端应用

    1. 场景后端存在N个tomcat实例,前端通过nginx反向代理和负载均衡. tomcat1      tomcatN         |                 |        |    ...