前端promise知识点笔记

前端 Promise 博客笔记

在前端开发中,异步操作是非常常见的,比如网络请求、定时器等。而 Promise 作为处理异步操作的重要方案,极大地改善了异步代码的可读性和可维护性。下面就来详细梳理一下 Promise 的相关知识。

一、Promise 的基本概念

Promise 是一个对象,它代表了一个异步操作的最终完成或者失败,及其结果值。简单来说,Promise 就像一个容器,里面存放着某个未来才会结束的事件(通常是一个异步操作)的结果。

Promise 有三种状态:

  • pending(进行中):初始状态,既不是成功,也不是失败。
  • fulfilled(已成功):异步操作完成,此时会调用 then 方法指定的回调函数。
  • rejected(已失败):异步操作失败,此时会调用 catch 方法指定的回调函数。

需要注意的是,Promise 的状态一旦改变,就会永久保持该状态,不会再发生变化。状态的改变只有两种可能:从 pending 变为 fulfilled,或者从 pending 变为 rejected。

二、Promise 的基本用法

创建一个 Promise 实例需要传入一个 executor 函数,该函数有两个参数,分别是 resolve 和 reject。resolve 函数的作用是将 Promise 的状态从 pending 变为 fulfilled,并将异步操作的结果作为参数传递出去;reject 函数的作用是将 Promise 的状态从 pending 变为 rejected,并将异步操作失败的原因作为参数传递出去。


const promise = new Promise((resolve, reject) => {

// 异步操作

setTimeout(() => {

const randomNum = Math.random();

if (randomNum > 0.5) {

resolve(randomNum); // 成功时调用resolve

} else {

reject(new Error('随机数小于等于0.5')); // 失败时调用reject

}

}, 1000);

});

三、Promise 的常用方法

then () 方法

then () 方法用于指定当 Promise 状态变为 fulfilled 时的回调函数。它可以接收两个参数,第一个参数是 fulfilled 状态的回调函数,第二个参数是 rejected 状态的回调函数(可选)。then () 方法返回一个新的 Promise 实例,因此可以采用链式调用的方式。


promise.then(

(value) => {

console.log('成功:', value);

},

(error) => {

console.log('失败:', error);

}

);

catch () 方法

catch () 方法用于指定当 Promise 状态变为 rejected 时的回调函数,它相当于 then (null, rejection)。同时,catch () 方法还可以捕获前面 then () 方法执行过程中抛出的错误。


promise

.then((value) => {

console.log('成功:', value);

throw new Error('在then中抛出错误');

})

.catch((error) => {

console.log('失败:', error);

});

finally () 方法

finally () 方法用于指定无论 Promise 状态是 fulfilled 还是 rejected,都会执行的操作。它的回调函数不接收任何参数,因为无法知道 Promise 的最终状态。


promise

.then((value) => {

console.log('成功:', value);

})

.catch((error) => {

console.log('失败:', error);

})

.finally(() => {

console.log('无论成功失败都会执行');

});

四、Promise 的静态方法

Promise.all()

该方法接收一个可迭代对象(通常是数组)作为参数,返回一个新的 Promise。当数组中所有的 Promise 都变为 fulfilled 状态时,新的 Promise 才会变为 fulfilled 状态,其结果是所有 Promise 结果组成的数组;如果数组中有一个 Promise 变为 rejected 状态,新的 Promise 就会立即变为 rejected 状态,其结果是该 rejected 的原因。


const promise1 = Promise.resolve(1);

const promise2 = Promise.resolve(2);

const promise3 = Promise.resolve(3);

Promise.all([promise1, promise2, promise3])

.then((values) => {

console.log(values); // [1, 2, 3]

})

.catch((error) => {

console.log(error);

});

Promise.race()

race () 方法同样接收一个可迭代对象作为参数,返回一个新的 Promise。只要数组中有一个 Promise 的状态发生改变(无论是 fulfilled 还是 rejected),新的 Promise 就会立即以相同的状态和结果改变。


const promise1 = new Promise((resolve) => {

setTimeout(resolve, 100, 'one');

});

const promise2 = new Promise((resolve) => {

setTimeout(resolve,200, 'two');

});

Promise.race([promise1, promise2])

.then((value) => {

console.log(value); // 'one',因为promise1先完成

});

Promise.resolve()

该方法返回一个以给定值解析后的 Promise 实例。如果该值是一个 Promise,那么返回的 Promise 会采用它的状态;如果该值是一个 thenable 对象(即具有 then 方法),则会将其转换为 Promise 并执行 then 方法;否则,返回的 Promise 状态为 fulfilled,结果为该值。


const promise = Promise.resolve(42);

promise.then((value) => {

console.log(value); // 42

});

Promise.reject()

该方法返回一个状态为 rejected 的 Promise 实例,结果为给定的错误信息。


const promise = Promise.reject(new Error('出错了'));

promise.catch((error) => {

console.log(error); // Error: 出错了

});

五、Promise 解决的问题

在 Promise 出现之前,我们处理异步操作主要使用回调函数。但是,当存在多个嵌套的异步操作时,就会产生 “回调地狱”,代码的可读性和可维护性极差。

例如,多层嵌套的回调:


setTimeout(() => {

console.log('第一层');

setTimeout(() => {

console.log('第二层');

setTimeout(() => {

console.log('第三层');

// 更多层嵌套...

}, 1000);

}, 1000);

}, 1000);

而使用 Promise 可以将嵌套的回调改为链式调用,使代码更加清晰、直观:


new Promise((resolve) => {

setTimeout(() => {

console.log('第一层');

resolve();

}, 1000);

})

.then(() => {

return new Promise((resolve) => {

setTimeout(() => {

console.log('第二层');

resolve();

}, 1000);

});

})

.then(() => {

setTimeout(() => {

console.log('第三层');

}, 1000);

});

六、使用 Promise 的注意事项

  1. 避免在 Promise 内部使用同步代码,因为 Promise 的回调函数是异步执行的,同步代码可能会导致不符合预期的结果。
  1. 不要忘记处理 Promise 的错误,否则错误可能会被默默忽略,难以排查。可以使用 catch () 方法统一捕获错误。
  1. 在 then () 方法中返回一个新的 Promise,可以实现异步操作的串行执行;使用 Promise.all () 可以实现异步操作的并行执行,但要注意其中一个失败会导致整个 Promise.all () 失败。
  1. 不要过度使用 Promise,对于简单的异步操作,使用回调函数可能更加简洁。

总之,Promise 是前端处理异步操作的重要工具,掌握它的使用方法和相关特性,能够极大地提高异步代码的质量和开发效率。在实际开发中,我们还会结合 async/await 等语法,让异步代码更加简洁、易读。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值