1.什么是回调地狱?
-
1.定义:在异步编程中,多层嵌套导致代码变得难以阅读和维护的情况。这种情况通常发生在多个异步操作,每个操作都依赖于前一个操作的结果时,代码中充斥着大量的回调函数。
-
2.写一个回调地狱的例子
js
function callback1(cb) {
setTimeout(() => {
console.log('回调函数1');
// 获取到一个数据
const data = 100
cb(data)
}, 1000)
}
function callback2(data, cb) {
setTimeout(() => {
console.log('回调函数2');
const data2 = data + 1
cb(data2)
}, 1000)
}
function callback3(data) {
setTimeout(() => {
console.log(`拿到需要的data数据${data}`);
}, 1000)
}
callback1((data) => {
callback2(data, (data2) => {
callback3(data2)
})
})
看了上面回调地狱的例子,是不是一时还不知道怎么调用,这就导致代码难以阅读和维护,所以这时候 Promise 就横空出世了。
2.什么是Promise?
上面的回调地狱问题只是抛砖引玉,下面是我们真正的主角:Promise。
Promise:JS中的Promise是一种处理异步操作的机制,可以更好的处理回调地狱问题。
3.Promise的3种状态
-
1.pending:待定
-
2.fulfilled:已兑现
-
3.rejected:已拒绝
4.Promise的3个实例方法
-
1.then:当 Promise 返回的状态为成功时要执行的回调函数。
-
2.catch:当 Promise 返回的状态为失败时要执行的回调函数。
-
3.finally:当 Promise 返回的状态不管是成功还是失败时要执行的回调函数。
5.Promise常用的6个静态方法
序号 | 方法名称 | 定义 |
---|---|---|
1 | Promise.resolve() | 创建一个立即成功的 Promise 对象,其结果就是你给它的值。 |
2 | Promise.reject() | 创建一个立即失败的 Promise 对象,其拒绝原因就是你指定的值。 |
3 | Promise.all() | 接收一个 Promise 对象数组,等对象数组中的Promise全部都成功解决后,返回一个包含所有成功结果的数组,按照输入的顺序排列。 |
4 | Promise.race() | 接收一个 Promise 对象数组,立即返回第一个解决的结果,不论结果是成功还是失败。 |
5 | Promise.allSettled() | 接收一个Promise对象数组,等对象数组中的Promise全部都解决后,不论结果是成功还是失败都会全部返回,返回一个包含所有结果的数组,按照输入的顺序排列。 |
6 | Promise.any() | 接收一个Promise对象数组,立即返回第一个成功解决的结果。如果全部失败,返回一个被拒绝的带有拒绝原因的数组。 |
6.手写Promise.all
js
function promiseAll(promiseArr) {
return new Promise((resolve, reject) => {
const res = []
let completed = 0
const len = promiseArr.length
for (let i = 0; i < len; i++) {
Promise.resolve(promiseArr[i]).then(val => {
res[i] = val
completed++
if (completed === len) {
resolve(res)
}
}).catch(error => {
reject(error)
})
}
})
}
7.手写Promise.race
js
function promiseRace(promiseArr) {
return new Promise((resovle, reject) => {
const len = promiseArr.length
if (len === 0) return;
for (let promiseItem of promiseArr) {
Promise.resolve(promiseItem).then(resovle, reject)
}
})
}
8.手写Promise.any
js
function promiseAny(promiseArr) {
return new Promise((resolve, reject) => {
const errors = [], len = promiseArr.length
let count = 0;
for (let i = 0; i < len; i++) {
Promise.resolve(promiseArr[i]).then(val => {
resolve(val)
}).catch(err => {
errors[i] = err
count++
if (count === len) {
reject(new AggregateError(errors, '所有的Promise都被拒绝'))
}
})
}
})
}
tips:如果你实在觉得还不够,你还想要懂得更多,如果你凑巧精力十足,还可以去手写一下Promise是吧?相关资料已帮你备好,请
查阅
。
9.使用Promise改写上面回调地狱代码
js
function promise1() {
return new Promise(resove => {
setTimeout(() => {
console.log('回调函数1');
const data = 100
resove(data)
}, 1000)
})
}
function promise2(data) {
return new Promise(resove => {
setTimeout(() => {
console.log('回调函数2');
const data2 = data + 1
resove(data2)
}, 1000)
})
}
function promise3(data) {
return new Promise(resolve => {
setTimeout(() => {
console.log(`拿到需要的data数据${data}`);
resolve()
}, 1000)
})
}
promise1().then(val => {
return promise2(val)
}).then(val => {
return promise3(val)
}).catch(err => {
console.log(err);
})
Promise 使用链式调用的方式解决上面的回调地狱问题,使得代码容易阅读和维护。
10.async/await
1.定义
async/await 是JS中处理异步操作的一种语法,是基于 Promise 的一种更简洁、更易读的方式。这种语法让异步代码看起来和写起来更像同步代码,从而减少了代码的复杂性。
2.async 关键字
-
定义 :async 是一个放在函数定义前的关键字,它使得函数总是返回一个 Promise 。如果函数返回的不是 Promise ,该返回值将被自动包装在一个 Promise 中。
-
用法 :当你在一个函数声明前加上 async,这个函数就成为了一个异步函数。
3.await 关键字
-
定义 :await 只能在 async 函数内部使用。它会暂停异步函数的执行,等待 Promise 的解决(fulfill)或拒绝(reject),然后继续异步函数的执行并返回解决结果。
-
用法 :await 后面通常跟着一个 Promise 。它使得代码等待直到 Promise 解决,并返回结果。
4.async/await优点
-
1.代码可读性:使得异步代码更容易阅读和理解。
-
2.错误处理 :可以使用传统的
try/catch
块来捕获错误。 -
3.减少回调函数 :避免了 Promise 链中嵌套
.then()
和.catch()
方法的需要。
11.使用 async/await 改写上面 Promise 代码
js
function promise1() {
return new Promise(resove => {
setTimeout(() => {
console.log('回调函数1');
const data = 100
resove(data)
}, 1000)
})
}
function promise2(data) {
return new Promise(resove => {
setTimeout(() => {
console.log('回调函数2');
const data2 = data + 1
resove(data2)
}, 1000)
})
}
function promise3(data) {
return new Promise(resolve => {
setTimeout(() => {
console.log(`拿到需要的data数据${data}`);
resolve()
}, 1000)
})
}
async function runPromise() {
try {
const val1 = await promise1()
const val2 = await promise2(val1)
await promise3(val2)
} catch (err) {
console.log(err);
}
}
runPromise()