深入理解 JavaScript 中的 Promise

在 JavaScript 中,Promise 是处理异步编程的重要工具。它可以让我们以更加优雅和可读的方式书写异步代码,减少回调地狱(callback hell)现象。

一、Promise 的基本概念

Promise 是一个表示异步操作最终完成或失败的对象。它有三种状态:

  1. Pending(待定):初始状态,既不是成功,也不是失败。
  2. Fulfilled(已兑现):操作成功完成。
  3. Rejected(已拒绝):操作失败。

每个 Promise 对象可以通过 then 方法进行链式调用,处理成功和失败的结果。

const myPromise = new Promise((resolve, reject) => {
    const isSuccess = true; // 模拟异步操作是否成功

    if (isSuccess) {
        resolve('操作成功!');
    } else {
        reject('操作失败!');
    }
});

myPromise
    .then(result => {
        console.log(result); // 输出:操作成功!
    })
    .catch(error => {
        console.log(error);
    });

二、Promise 的使用

Promise 的核心在于它的构造函数和 thencatchfinally 方法。

  • then 方法:用于指定操作成功时的回调;返回一个新的 Promise
  • catch 方法:用于指定操作失败时的回调。
  • finally 方法:无论操作成功或失败,都会执行的回调。
const asyncFunction = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('异步操作完成!');
        }, 2000);
    });
};

asyncFunction()
    .then(result => {
        console.log(result); // 输出:异步操作完成!
        return '继续处理下一步';
    })
    .then(nextResult => {
        console.log(nextResult); // 输出:继续处理下一步
    })
    .catch(error => {
        console.log('错误:', error);
    })
    .finally(() => {
        console.log('无论成功或失败,都会执行的代码块');
    });

三、Promise 的进阶用法

  1. Promise.all:用于并行处理多个 Promise,解决所有 Promise 的结果,或只要有一个失败就返回失败。
const promise1 = new Promise((resolve) => {
    setTimeout(() => resolve('第一个 Promise'), 1000);
});

const promise2 = new Promise((resolve) => {
    setTimeout(() => resolve('第二个 Promise'), 2000);
});

Promise.all([promise1, promise2])
    .then(results => {
        console.log(results); // 输出:["第一个 Promise", "第二个 Promise"]
    })
    .catch(error => {
        console.log('有一个 Promise 失败:', error);
    });
  1. Promise.race:只关注第一个 resolved 或 rejected 的 Promise
const promise1 = new Promise((resolve) => {
    setTimeout(() => resolve('第一个 Promise'), 1000);
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => reject('第二个 Promise 失败'), 500);
});

Promise.race([promise1, promise2])
    .then(result => {
        console.log('第一个完成:', result);
    })
    .catch(error => {
        console.log('第一个失败:', error); // 输出:第一个失败: 第二个 Promise 失败
    });

四、手写一个简单的 Promise 实现

下面是对 Promise 的一个简化版手写实现,着重展示核心逻辑:

class MyPromise {
    constructor(executor) {
        this.state = 'pending';
        this.value = undefined;
        this.reason = undefined;
        this.onFulfilledCallbacks = [];
        this.onRejectedCallbacks = [];

        const resolve = (value) => {
            if (this.state === 'pending') {
                this.state = 'fulfilled';
                this.value = value;
                this.onFulfilledCallbacks.forEach(fn => fn(value));
            }
        };

        const reject = (reason) => {
            if (this.state === 'pending') {
                this.state = 'rejected';
                this.reason = reason;
                this.onRejectedCallbacks.forEach(fn => fn(reason));
            }
        };

        try {
            executor(resolve, reject);
        } catch (error) {
            reject(error);
        }
    }

    then(onFulfilled, onRejected) {
        if (this.state === 'fulfilled') {
            onFulfilled(this.value);
        } else if (this.state === 'rejected') {
            onRejected(this.reason);
        } else {
            this.onFulfilledCallbacks.push(onFulfilled);
            this.onRejectedCallbacks.push(onRejected);
        }
    }
}

// 使用手写的 MyPromise
const promise = new MyPromise((resolve, reject) => {
    setTimeout(() => resolve('手写 Promise 完成!'), 1000);
});

promise
    .then(value => console.log(value))
    .catch(reason => console.log(reason));

结论

通过以上内容,我们对 Promise 的基本概念、使用方法以及一些高级用法有了更深入的理解。掌握 Promise 的使用,不仅可以帮助我们更好地处理异步操作,还能提高代码的可读性与可维护性。希望这篇文章能够帮助你更好地理解和使用 Promises。

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部