Promise 的理解

3 篇文章 0 订阅

Promise是JavaScript中一种处理异步编程的方式,它代表了一个异步操作的结果。一个Promise对象有三个状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。当异步操作完成时,Promise对象会从pending状态转换为fulfilled状态或rejected状态。

Promise通过then()和catch()方法来处理异步操作的结果。当异步操作成功完成时,then()方法会被调用,并将异步操作的结果传递给它。当异步操作失败时,catch()方法会被调用,并将错误信息传递给它。

通过使用Promise,我们可以更加方便地进行异步编程,避免了回调地狱的问题,使代码更加清晰易懂。

Promise的实现原理

Promise 的原理是基于状态机模型,它包括三种状态:Pending(等待态)、Fulfilled(完成态)和 Rejected(失败态)。在创建 Promise 对象时,它的初始状态为 Pending,表示异步操作尚未完成。

当异步操作完成时,可以调用 resolve 方法将 Promise 对象的状态从 Pending 改为 Fulfilled,并传递异步操作的结果;或者调用 reject 方法将 Promise 对象的状态从 Pending 改为 Rejected,并传递异步操作的错误信息。

一旦 Promise 对象的状态改变,它就不会再次改变,也就是说,Promise 对象是不可变的。

Promise 对象还提供了 then 方法用于处理异步操作的结果,它接收两个参数:onFulfilledonRejected,分别表示异步操作成功和失败时的回调函数。

Promise 对象的状态为 Fulfilled 时,会调用 onFulfilled 回调函数,传递异步操作的结果;当 Promise 对象的状态为 Rejected 时,会调用 onRejected 回调函数,传递异步操作的错误信息。

如果在 then 方法中返回一个新的 Promise 对象,那么后续的 then 方法将会等待这个新的 Promise 对象的状态改变,从而实现链式调用。

如果在 then 方法中抛出异常或返回一个 Rejected 状态的 Promise 对象,那么后续的 then 方法将直接调用 onRejected 回调函数,传递异常信息或 Promise 对象的错误信息。

总之,Promise 的原理是基于状态机模型,它提供了一种规范的方式来管理异步操作,使用 then 方法实现链式调用,通过 resolvereject 方法来改变 Promise 对象的状态,使用 onFulfilledonRejected 回调函数处理异步操作的结果或错误信息。

Promise解决多次调用的面条式代码

  1. 将每个异步操作封装在一个Promise对象中,并通过Promise的then方法来处理异步操作的结果。

  2. 将多个Promise对象组合成一个Promise链。在Promise链中,每个Promise对象的结果都依赖于上一个Promise对象的结果。可以通过返回一个新的Promise对象来实现Promise链。

  3. 在Promise链中,可以使用Promise的catch方法来处理错误信息。如果任何一个Promise对象出错,整个Promise链都会立即终止,并且会跳过后续的Promise对象。

function doSomething() {
  return new Promise((resolve, reject) => {
    // 异步操作
    setTimeout(() => {
      const result = Math.random();
      if (result > 0.5) {
        resolve(result);
      } else {
        reject(new Error('Something went wrong'));
      }
    }, 1000);
  });
}

function doSomethingElse(result) {
  return new Promise((resolve, reject) => {
    // 异步操作
    setTimeout(() => {
      const newResult = result * 2;
      if (newResult > 1) {
        resolve(newResult);
      } else {
        reject(new Error('Something else went wrong'));
      }
    }, 1000);
  });
}

doSomething()
  .then(result => doSomethingElse(result))
  .then(newResult => {
    console.log('Final result:', newResult);
  })
  .catch(error => {
    console.error('Error:', error);
  });

doSomething和doSomethingElse是两个异步操作,它们都返回一个Promise对象。在主函数中,首先调用doSomething函数,然后在它的then方法中调用doSomethingElse函数,最后在它的then方法中输出结果。如果任何一个Promise对象出错,整个Promise链都会立即终止,并且会跳过后续的Promise对象。

Promise.all的作用是使多个异步操作并行执行,并等待所有异步操作都完成后再进行下一步操作。它接收一个Promise对象数组作为参数,并返回一个新的Promise对象。当所有的Promise对象都完成时,会变为fulfilled状态,并且会将所有Promise对象的结果组成一个数组传递给它的then方法;如果其中任何一个Promise对象被rejected,则返回的Promise对象会立即变为rejected状态,并且会将第一个被rejected的Promise对象的错误原因传递给它的catch方法。

Promise.race作用是允许在多个异步操作中只取最快的结果,从而加速整个异步流程。

1.三种状态:

  • pending:初始状态
  • fulfilled: 意味着操作成功完成
  • rejected: 意味着操作失败

2.状态变化:

        pending ---> fulfilled 或 pending --> rejected (变化不可逆)

3.then 和 catch 对状态的影响:

        then 和 catch 正常状态都会返回 fulfilled,里面有报错则返回 rejected

4.链式调用

// 例一
Promise.resolve.then(() => { // then 返回的是 resolved 状态,所以下面的 catch 不会执行
  console.log(1); // 1
}).catch(() => {
  console.log(2);
}).then(() => {
  console.log(3); // 3  resolved
})

// 例二
Promise.resolve().then(() => { // 这里返回的是 rejected 状态,所以会执行下面的 catch
  console.log(1); // 1
  throw new Error('error1');
}).catch(() => { // 这里返回的是 fulfilled 状态,所以会执行下面的 then
  console.log(2); // 2
}).then(() => {
  console.log(3); // 3  resolved
})

// 例三
Promise.resolve().then(() => {
  console.log(1); // 1  rejected
  throw new Error('error1');
}).catch(() => {
  console.log(2); // 2 fulfilled
}).catch(() => {
  console.log(3);
})

// 例四
Promise.reject().catch(() => {
  console.log(1); // 1  fulfilled
}).then(() => {
  console.log(2); // 2 rejected
  throw new Error('error1');
}).catch(() => {
  console.log(3); // 3
});

Promise.all([p1, p2, p3, ...])

传入 Promise 数组,等待全部的 Promise 都 fulfilled 后,返回新的 Promise,包含所有的结果。一个失败,就返回失败。

Promise.race([p1, p2, p3, ...])

传入Promise 数组,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变,如果第一个就是失败了,就返回rejected。

简单举例说明:

const p1 = Promise.resolve(100);
const p2 = Promise.resolve(200);
const p3 = Promise.reject('抛出异常');
const p4 = Promise.all([p1, p2]);
const p5 = Promise.race([p1, p2]);
console.log('p4', p4);
console.log('p5', p5);

const p1 = Promise.resolve(100);
const p2 = Promise.resolve(200);
const p3 = Promise.reject('抛出异常');
const p4 = Promise.all([p1, p2, p3]);
const p5 = Promise.race([p1, p2, p3]);
console.log('p4', p4);
console.log('p5', p5);

5. Promise 优缺点:

优点:

  • 实现链式调用,避免了层层嵌套的回调函数。
  • Promise 对象提供统一的接口,使异步操作更加容易控制。
  • 可以同时执行多个异步操作,结果返回后统一处理。

缺点:

  • 一旦开始执行就无法取消;
  • 无法进度追踪,当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值