一、异步、同步、回调
同步
- 如果能直接拿到结果,那就是同步
- 比如你在医院挂号,你拿到号才会离开窗口,同步任务可能消耗 10 毫秒,也可能需要 3 秒,总之不拿到结果你是不会离开的
异步
- 如果不能直接拿到结果,那就是异步
- 比如你在餐厅门口等位,你拿到号可以去逛街,什么时候才能真正吃饭呢?
- 你可以每10分钟去餐厅问一下(轮询)
- 你也可以扫码用微信接收通知(回调)
回调 (callback)
- 你写给自己用的函数,不是回调
- 你写给别人用的函数,就是回调
- 写了却不调用,给别人调用的函数,就是回调
异步和回调的关系
- 关联
- 异步任务需要在得到结果时通知 JS 来拿结果
- 怎么通知呢?
- 可以让 JS 留一个函数地址(电话号码)给浏览器
- 异步任务完成时浏览器调用该函数地址即可(拨打电话)
- 同时把结果作为参数传给该函数(电话里说可以来吃了)
- 这个函数是我写给浏览器调用的,所以是回调函数
- 区别
- 异步任务需要用到回调函数来通知结果
- 但回调函数不一定只用在异步任务里
- 回调可以用到同步任务里
array.forEach( n => console.log(n) ) 就是同步回调
判断同步异步
- 如果一个函数的返回值处于
- setTimeout
- AJAX(即 XMLHttpRequest)
- AddEventListener
- 这三个东西内部,那么这个函数就是异步函数
二、如果异步任务有两个结果,成功或失败
- 方法一:回调接受两个参数
fs.readFile('./1.txt', (error, data)=>{
if(error){ console.log('失败'); return }
console.log(data.toString())
})
- 方法二:搞两个回调
ajax('get','/1.json', data=>{}, error=>{})
ajax('get', '/1.json', {
success: ()=>{}, fail: ()=>{}
})
- 这些方法的不足
- 不管方法一还是方法二,都有问题
- 不规范,名称五花八门,有人用 success + error,有人用 success + fail,有人用 done + fail,
- 容易出现回调地狱,代码变得看不懂
- 很难进行错误处理
- 改进方法: 使用promise
return new Promise((resolve, reject)=>{})
第一步
return new Promise((resolve,reject)=>{...})
任务成功则调用 resolve(result)
任务失败则调用 reject(error)
resolve 和 reject 会再去调用成功和失败函数
第二步
使用 .then(success, fail) 传入成功和失败函数
三、axios
- 目前最新的 AJAX 库
代码示例
axios.get(
.then( response =>
console.log(response)
)
axios 高级用法
- JSON 自动处理
- axios 如果发现响应的 Content-Type 是 json就会自动调用 JSON.parse
- 请求拦截器
- 响应拦截器
- 可以生成不同实例(对象)