JS基础之Promise

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()
相关推荐
啾咪orJIUMI2 小时前
Vue 3 + 高德地图封装实战:点位、区域、Loca 流光与 Vue 信息窗体
前端·vue.js
掘金者阿豪2 小时前
AI数据库不只是向量检索:从数据语义到库内智能计算的技术演进
前端
梦里寻码2 小时前
我用 NestJS + Vue3 写了一套完整的研发管理系统(58 表 / 229 API / 130 项断言,全开源
前端·后端·算法
FRing032 小时前
vue2干货总结8(路由模块封装、router-link、声明式导航、路由重定向、编程式导航)
开发语言·前端·vue.js·vue2
SameX2 小时前
HarmonyOS ArkUI Dialog 复用 用 @CustomDialog + enum type 做多类型统一管理的做法
前端
AiMan2 小时前
豆包爱学还是不可以导出左侧所有对话,只能单容导出,方法不对吗
前端
AiMan3 小时前
Grok生成的内容能否下载吗?
前端
徐小夕3 小时前
JitArchives,一款基于JitWord协同AI文档打造的企业级电子档案系统
前端·vue.js·github
陈随易3 小时前
Node.js 2026上半年都有哪些性能提升?
前端·后端·程序员
墨林陌4 小时前
AI 热点日报(2026-11-09):苹果代理式Siri曝光,Anthropic推进IPO,编码智能体实测翻车
前端