异步操作应该是以前学习 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. hdu2544 最短路 Dijkstra算法

    最短路(Dijkstra算法模板题) Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  2. css+div基本知识;

    1.居中: <div class="test"></div> css: .test{ margin: auto; //一行中居中: } 2.IE与其他浏览器 ...

  3. POJ3417 LCA+树dp

    http://poj.org/problem?id=3417 题意:先给出一棵无根树,然后下面再给出m条边,把这m条边连上,然后每次你能毁掉两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂 ...

  4. OGNL中的#、%和$符号的用法

    转自:https://blog.csdn.net/qq_24963197/article/details/51773224 一.OGNL中的#.%和$符号 1.#符号的三种用法 1)访问非根对象属性, ...

  5. js和jQuery中的事件绑定与普通事件

    普通事件,是指直接对元素进行事件注册,然后触发 而事件绑定是将事件注册到元素上 两者区别就是在于普通事件不可以重复添加多个事件,若添加也会覆盖,只会触发其中一个事件(最后注册的那个) 而事件绑定是可以 ...

  6. angular中的服务

    angular中的服务 angular中的服务相当于一个状态管理,可以将数据放在服务里面进行获取以及编辑. 服务的安装命令: ng g service count 安装好后,会在服务的ts文件中引入一 ...

  7. HDU - 4614 Vases and Flowers(二分+区间修改)

    https://cn.vjudge.net/problem/HDU-4614 题意 n个花瓶,m个操作,花瓶里面有的有花,有的是空的.1操作是从a开始往右放b朵花,花瓶有了的不放,跳过,直到a右边都放 ...

  8. Excel公式使用

    IF语句: 想要给F16自动求值,可以利用IF语句,如下: 语句: 同时,还需要设置B27的单元格格式为“常规”

  9. AAndroid Studio的\drawable还是mipmap

    图片应该放在drawable文件夹下,而mipmap文件夹只适合放app icons

  10. string 与 stringbuilder效率相差很大

    方式一: (while ((line = sr.ReadLine()) != null) { strData +=(line+"\r\n"); } 方式二: while ((lin ...