- 回调函数 本质上就是一个普通函数
- 一个函数A以实参的形式传递到 函数B中,在函数B中, 以形参的方式调用函数A,此时 函数A就可以称为 函数B 的回调函数
- 回调函数的使用场景为异步代码的解决方案
function A() {
console.log('我是函数A')
}
function B(callback) {
callback()
}
B(A)
//基础版
function fn(callback = () => { }) {
console.log('班长, 帮我买瓶水')
setTimeout(() => {
console.log('班长, 买到水了')
callback()
}, 3000)
}
function jinnang() {
console.log('在帮买一箱水')
}
fn(jinnang
// 网络请求模拟
function fn(chenggong, shibai) {
const timer = Math.ceil(Math.random() * 3000)
console.log('班长, 去帮我买瓶水')
setTimeout(() => {
if (timer > 2500) {
console.log('买水失败, 用时: ', timer)
shibai()
} else {
console.log('买水成功, 用时: ', timer)
chenggong()
}
}, timer)
}
fn(
() => { console.log('谢谢班长, 我和你开玩笑的, 退了吧!') },
() => { console.log('买不到就别回来了') }
)
回调地狱
这不是我们写代码的时候出现的某个漏洞,只是我们在利用回调函数解决问题的时候, 代码量多了之后的一个视觉体验
回调地狱的代码不利于我们去维护或者管理, 所以后续再处理异步任务的时候
我们需要一些更加简洁的方法,此时出现了一个东西 叫做 promise 他也是一个异步代码的解决方案
// 调用 fn 函数 班长就回去 买水
function fn(chenggong, shibai) {
const timer = Math.ceil(Math.random() * 3000)
console.log('班长, 去帮我买瓶水')
setTimeout(() => {
if (timer > 2900) {
console.log('买水失败, 用时: ', timer)
shibai()
} else {
console.log('买水成功, 用时: ', timer)
chenggong()
}
}, timer)
}
/**
* 需求:
* 在班长买水失败后, 让他再次去买水(重新调用 fn 函数)
*
* 新需求: 如果班长 第二次也失败了, 让他继续去买水
*
* 新需求: 第一次买水成功的时候, 让班长再去买一箱饮料
*/
fn(
() => {
fn(
() => { console.log('班长买完水后, 又买了一箱饮料') },
() => { console.log('班长就买了一瓶水, 他不愿意给你们买饮料') }
)
},
() => {
fn(
() => { console.log('班长第二次买水 成功了') },
() => {
fn(
() => { console.log('班长第三次买水 成功了') },
() => { console.log('班长第三次买水 又失败了, 确实不争气') }
)
}
)
}
)
promise
- 作用: 一种新的异步代码封装方案, 用来代替 回调函数的
- promise 的三个状态
- 持续: pending
- 成功: fulfilled
- 失败: rejected
promise 只会在持续状态转换为 成功,或者 从持续状态转换为 失败 promise 的基本语法: promise 是 JS 内置的一个构造函数
const p = new Promise()
- new Promise 得到的对象 我们叫做 promise 对象,
promise 对象上 有一些方法
- then 方法 (会在 promise 状态成功的时候 执行)
- catch 方法 (会在 promise 状态失败的时候 执行)
const p = new Promise(function (resolve, reject) {
/**
* 形参名无所谓
* 第一个形参: 内部的值是一个函数, 调用之后可以将当前这个 promise 的状态设置为 成功
* 第二个形参: 内部的值是一个函数, 调用之后可以将当前这个 promise 的状态设置为 失败
*/
// 书写我们的异步代码
const timer = Math.ceil(Math.random() * 3000)
console.log('班长, 去帮我买瓶水')
setTimeout(() => {
if (timer > 1500) {
console.log('买水失败, 用时: ', timer)
// shibai()
reject()
} else {
console.log('买水成功, 用时: ', timer)
// chenggong()
resolve()
}
}, timer)
})
// console.log('打印 变量 p: ', p)
p.then(() => {
console.log('如果我这行内容打印, 说明 promise 的状态为 成功')
})
p.catch(() => {
console.log('如果我这行内容打印, 说明 promise 的状态为 失败')
})