回调函数 callback
- 回调函数嘛 就是在一个函数结束时去调用另外一个函数 当然是以参数传递的方式
- 假设现在有函数a和函数b 将b函数以参数形势传入 a函数中 在a函数内部调用 b函数
function a (callback) {
console.log('我是a')
setTimeout(() => callback() ,1000)
}
function b () {
console.log('我是b')
}
a(b)
- 封装一个异步函数 (通常用于网络请求)
function myCallback (callback) {
let timer = Math.ceil(Math.random() * 3000)
setTimeout(() => {
console.log('异步代码开始执行')
callback()
},timer)
}
function fn () {
console.log('异步代码执行结束 我才执行')
}
myCallback(fn)
- 实际上网络请求有成功 肯定也有失败 所以上个栗子 也就是个栗子
- 栗子思路:
- 首先我们创建一个结束时间随机的倒计时器
- 我们规定 当结束时间大于1500ms为请求失败
- 小于1500ms即为请求成功
- 函数接收两个参数success为成功是调用 fail为失败时调用
function myCallback (success, fail) {
let timer = Math.ceil(Math.random() * 3000)
setTimeout(() => {
if (timer > 1500) {
console.log('网络连接失败啦')
fail()
} else {
console.log('请求成功')
success()
}
},timer)
}
myCallback(
() => console.log('数据已帮您更新'),
() => console.log('请检查您的网络')
)
回调地狱
- 回调地狱并不是bug 而是一种不利于阅读的代码格式
- 借用上一个栗子
- 第一次请求成功后继续请求...n次后效果..
function myCallback (success, fail) {
let timer = Math.ceil(Math.random() * 3000)
setTimeout(() => {
if (timer > 1500) {
console.log('网络连接失败啦')
fail()
} else {
console.log('请求成功')
success()
}
},timer)
}
myCallback(
() => {
console.log('数据已帮您更新')
myCallback(
() => {
console.log('数据已帮您更新')
myCallback(
() => console.log('数据已帮您更新'),
() => console.log('请检查您的网络')
)
},
() => console.log('请检查您的网络')
)
},
() => console.log('请检查您的网络')
)
- 当然肯定有解决方案
认识 Promise
- Pro.then(res => {
console.log(res)
}).then(res => {
console.log(res)
})....
.catch( res => {
console.log('失败了')
})
async 和 await
- 和Promise 配合
- 可以让异步代码做到和同步代码一样的效果(类似)
async关键字 必须书写在函数名前面
await关键字的含义
- 需要等待
await后面的Promise对象执行完成之后才会继续执行后续代码
async 和 await 语法的缺点
- await无法捕获到promise的失败状态 也就是说在promise状态为失败的时候 后续代码将无法执行
- 解决方案1
- 手动修改Promise的值(状态) 让其永远都是成功状态、
- 然后可以让其返回一个数组 或者对象 对象或者数组内存放一个标志值
- 后续我们只需要判断其的数值的类型
- 解决方案2
Promise 的其他方法
- Promise()的实例化对象上还有一个方法
- finally 方法会在Promise执行结束之后才会执行(状态转换完成之后)
- 无论状态是成功还是失败 都会执行
- finally(res => {})
Promise实例化对象上的其他方法
all 方法
- 该方法接收一个数组
- 数组内可以传递多个Promise实例化对象
- 类似数中的
every()方法
- 当每一个传入对象的状态都为成功时 all方法会成功
- 但凡有一个对象失败 all() 方法都会失败
race方法
- 接收一个数组
- 数组内接收多个Promise的实例化对象
- 该方法类似数组的some方法
- 都是对象中有一个成功 状态就为成功
- 区别
some()方法是针对所有项
race()方法只针对第一项
- 当传入的对象中的第一项的结果为成功
race()方法成功
- 否则
race() 方法为失败
allSettled()
- 接收一个数组
- 数组内可以传入多个Promise的实例化对象
- 在
allSettled()方法内部只会执行then()
- 会将每一个对象的状态储存在数组中
数组扁平化
- 数组扁平化 类似深拷贝
- 数组扁平化 意指将多维数组装换为一维数组
- 思路:
- 首先构造一个函数
- 然后遍历数组 顺便对每一项做数据类型检测
- 检测方法
Object.prototype.toString.call(item)
constructor === Array
item instance Array
- 基本数据类型直接添加到新数组内
- 数组内的数组 继续调用分解函数(递归)
- 直到数组内没有数组
let arr = [1, 2, 3, [4, 5, [6, 7, [8, 9, [10, 11]]]]]
function myFlat (origin) {
let newArr = []
function inner(innerOrigin) {
innerOrigin.forEach(item => {
if (Object.prototype.toString.call(item) === '[object Array]'){
inner(item)
} else {
newArr.push(item)
}
})
}
inner(origin)
return newArr
}