文章目录
异步、同步
-
同步:可以直接拿到结果 比如医院挂号
-
异步:不能直接拿到结果 比如:网红餐厅 两种方式:自己问(轮询) 微信提醒(回调)
其实AJAX的请求与响应就是异步,send()后无法打出console.log(request.response)
js提供onreadystatechange()构造函数,只有当request.readystate值为4时,浏览器才回调这个函数,这个函数是js提供给浏览器用的,
request.send()
console.log(request.response)
setTimeout(()=>{console.log(request.response)},2000)
无结果
h1 {
color: blue;
}
回调 callback 写给别人用的函数
function f1(){console.log('hi')}
function f2(fn){fn()}
f2(f1)
hi
- 我没有调用f1
- f2调用了f1
- f1传给了f2
f1是回调函数,f2是我自己调用的
- 为什么f2一定会调用f1?
f1创建出来就是让调用的,f2接受fn 参数,而f2必定会调用f1
- 为什么f1为什么是回调函数,不是字符串啥的?
字符串会报错,不可能不是函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tdO1OtC8-1591167979904)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200510212331167.png)]
异步与回调的关系
联系:异步是得到结果时再通知js,js留函数地址给浏览器,异步任务完成,浏览器调用函数地址,同时把结果作为参数传给该函数,这个函数就我写给浏览器调用的,叫调用函数
区别:异步任务可以用回调函数来通知结果,当然也有轮询
回调函数不只是可以用于异步,还可用于同步回调 如forEach((item)=>console.log(item))
异步函数 函数返回值处于三个内部
- AJAX(XMLHttpRequest)
- setTimeout
- addEventListener
AJAX不要设置同步( request.open(‘GET’, ‘2.js’,false)),这样只能一个执行完再执行另外一个,造成无法操作
异步函数 摇骰子案例
function 摇骰子(){
setTimeout(()=>{
return parseInt(Math.random()*6+1) //1-6的随机数
},2000)
}
摇骰子()
undefined
此时摇骰子()没有return,调用返回undefined;setTimeout()有函数值,有return
如何拿到异步函数的值?引入回调函数
function f1(x){console.log(x)} //回调函数 把异步完成的结果作为参数
摇骰子(f1) //把函数地址给他
两步变化
function 摇骰子(fn){
setTimeout(()=>{
fn( parseInt(Math.random()*6+1))
},2000)
}
搞定 可以拿到异步任务值了
摇骰子(f1)
1
摇骰子(f1)
3
回调函数简化代码
x=>console.log(x)
console.log
function f1(x){console.log(x)}
摇骰子(f1)
摇骰子(x=>console.log(x))
undefined
VM1465:1 4
摇骰子(console.log)
undefined
VM1407:3 3
简化中的坑 参数必须一致
[‘1’,‘2’,‘3’].map((item)=>{return parseInt(item)})
['1','2','3'].map(parseInt)
(3) [1, NaN, NaN]
['1','2','3'].map((item,index,arr)=>{return parseInt(item,index,arr)})
(3) [1, NaN, NaN]
//正确格式
['1','2','3'].map((item,index,arr)=>{return parseInt(item)})
(3) [1, 2, 3]
['1','2','3'].map((item)=>{return parseInt(item)})
(3) [1, 2, 3]
由于map有三个参数 不能直接最简化,最简化无法三对 1
总结-异步1个结果
- 异步任务不能拿到结果
- 传回调给异步任务
- 异步任务完成进行调用回调
- 调用时结果作为参数来回调
Promise的用法 处理两个结果
存在三种问题
- 回调地狱
- 回调名称不规范,顺序不规范。成功与失败时,用success+error,success+fail,done+fail
- 很难进行错误处理
析构赋值
const{success,fail}=options
//展开代码为
const success=options.success
const fail=options.fail
封装AJAX
//封装AJAX
ajax = (method, url, options) => {
const {
success,
fail
} = options
const request = new XMLHttpRequest()
request.open(method, url)
request.onreadystatechange = () => {
if (request.readyState === 4) {
if (request.status < 400) {
success.call(null, request.response)
} else {
fail.call(null, request.request.status)
}
}
}
request.send()
}
//对封装好的AJAX调用
ajax('get', '/xxx', {
success(response) {},
fail: (request, status) => {}
})
两种函数缩写
success(response){} //有this
fail:(request,status)=>{} //无this
用Promise来调用AJAX
1.修改ajax源码,加return new Promise((resolve,reject)=>{...})
任务成功调用 resolve(result)
任务失败调用 reject(error)
resolve和reject会调用成功和失败函数
//封装AJAX
ajax = (method, url, options) => {
return new Promise((resolve,reject)=>{
const {
success,
fail
} = options
const request = new XMLHttpRequest()
request.open(method, url)
request.onreadystatechange = () => {
if (request.readyState === 4) {
if (request.status < 400) {
resolve.call(null, request.response)
} else {
reject.call(null, request.request.status)
}
}
}
request.send()
})
}
2.promise调用AJAX
ajax('get','/xxx').then((response)=>{},(request)=>{})
ajax返回的是.then方法的对象
封装的ajax的缺点
- post无法上传数据
- 不能设置请求头 request.setRequestHeader(key,value)
怎么解决:
- 用jQuery.ajax:JQuery中文文档=》jQuery.ajax看参数,实例
axios 目前最新的库
axios 作弊表
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
- JSON自动处理,把content-Type为JSON的转为对象,自动调用JSON.Parse
- 请求和响应拦截器
- 生成不同实例
总结
1.异步是什么?
不能直接拿到请求
2.异步为什么用回调?
为了拿到这个结果
3.回调存在的三个问题?
- 回调地狱
- 成功或者失败的命名和顺序问题:successuccess+error,success+fail,done+fail
- 很难进行错误处理
4.Promise是1976年提出的一种设计模式
5.如何用Promise?
return new Promise((resolve,reject)=>{})
6.axios怎么用?
https://www.bootcdn.cn/ 里axios
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.min.js"></script>
<script>
axios.get('/xxx')
//成功时返回
.then(function (response) {
console.log(response);
})
//失败时返回
.catch(function (error) {
console.log(error);
});
</script>
7.Promise是前端解决异步的统一方案