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()
相关推荐
无限大.1 小时前
前端知识速记--HTML篇:src和href
前端·html
子非鱼9211 小时前
两栏布局、三栏布局、水平垂直居中
前端·javascript·css
程序猿小D2 小时前
第三百五十八节 JavaFX教程 - JavaFX滑块
java·前端·数据库
GISer_Jing3 小时前
React中useState()钩子和函数式组件底层渲染流程详解
前端·react.js·前端框架
私人珍藏库4 小时前
Google Chrome-便携增强版[解压即用]
前端·chrome
我的青春不太冷5 小时前
【实战篇章】深入探讨:服务器如何响应前端请求及后端如何查看前端提交的数据
运维·服务器·前端·学习
Anlici6 小时前
2025前端高频面试题--CSS篇
前端·css
追光少年33226 小时前
Learning Vue 读书笔记 Chapter 4
前端·javascript·vue.js
软件2056 小时前
【Vite + Vue + Ts 项目三个 tsconfig 文件】
前端·javascript·vue.js
老大白菜6 小时前
在 Ubuntu 中使用 FastAPI 创建一个简单的 Web 应用程序
前端·ubuntu·fastapi