Promise

Promise

一个容器,保存着某个未来会结束的事件(通常是一个异步操作)的结果

当有大量的计算时,整个系统会卡住,都会使用异步的方式 [回调地狱: 回调嵌套] 来进行组织代码
回调嵌套不容易找出报错的地方
为解决回调地狱的问题,ES6提供了Promise

栗子:

setTimeout(() => {
        console.log("shenme");
      })
      console.log("liang");
      // liang 会比 shenme 先输出

如果想 liang这条事件 基于定时器完成

setTimeout(() => {
        console.log("shenme");

        console.log("liang");

      });

如果liang 这个事件也是异步函数

setTimeout(() => {
        console.log("shenme");
      }, random()) // random是个随机值,结束时间不确定

      setTimeout(() => {
        console.log("liang");
      }, random())

      // 如果想 liang这条事件 基于定时器完成,那么必须将其放在定时器中
      setTimeout(() => {
        console.log("shenme");

        setTimeout(() => {
          console.log("liang");
        }, random())
      }, random())
      // 这样的嵌套回调,称为: 回调地狱

为了避免这种情况,可使用Promise

// Promise是个构造函数,所以要new来创建
      /*new Promise();*/ // 必须接受回调函数,否则报错

      new Promise((resolve, reject) => {
        resolve(); // 表示Promise一旦执行,就成功了
        reject(); // 那么这条语句就不执行了,因为上一步已经确定了Promise的状态,内部状态不会再改变
      });

      // 将异步函数放在Promise的内部
      new Promise((resolve, reject) => {
        setTimeout(() => {
          /*console.log("liang");
          // 如果顺利执行到这一行,就结束

          resolve();*/ // 返回Promise状态

        // 但也有可能Promise的内部逻辑出错,导致出错
          try {
            console.log("liang");
            resolve('成功了');
          }catch (error) {
            reject(error);
          }

        }, 100)
        // 上面的异步事件,会传出一个信息msg,如果成功被第一个函数接受,然后调用,否则调用第二个函数
      }).then((msg) => {
        if (msg) {
          setTimeout(() => {
            console.log("梁");
          }, 100)
        }
      }, err => {

      })

如果想让事件2传给事件3,就return,如果return的是一个普通数据,所有默认成功,只有return 失败的Promise 对象,才会传出失败

.then((msg) => {
        console.log("梁2");

        // 如果想让事件2传给事件3,就return
          /*return '这是事件2传给事件3的'*/

        // 那么如何返回失败的去触发失败事件??return一个失败的Promise,在事件3中log error可见
          new Promise((resolve, reject) => reject('事件2失败了'));
          return undefined;

      }, err => {

      })

      // 还需要事件3基于事件2发生? 继续用.then()
      .then((msg) => {
        console.log("梁3");
      }, err => {
          console.log('事件2失败了');
      })
      // 如果事件1、2正常结束完,那么默认成功

catch()

以上代码输出:在这里插入图片描述
原因: Promise必须设置一个then 接受回调,当把Promise放在then 中,它是显示失败的,必须显示地去捕获这个错误

	 new Promise((res, rej) => rej('事件2失败了'))
              .then(
                  msg => {},
                  err => {
                      console.log(err)
                  }
              )
              
	// 可用catch 捕获
        return new Promise((res, rej) => rej('事件2失败了'))

      })
          .catch(err => {
              console.log(err);
          })

【注】Promise 内部的错误是会被其捕获掉的,不会影响后续代码的执行("冒泡"性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个 catch 语句捕获),所以最好写上catch 来捕获这个错误

all()

用于多个Promise实例,包装成一个新的Promise 实现

var p = Promise.all([p1,p2,p3]);

上面代码中,Promise.all 方法接受一个数组作为参数,p1、p2、p3 都是 Promise 对象的实例。
(Promise.all 方法的参数不一定是数组,但是必须具有 iterator 接口,且返回的每个成员都是 Promise 实例。)

p 的状态由 p1、p2、p3 决定,分成两种情况:

(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

rece

同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

var p = Promise.race([p1,p2,p3]);

只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的Promise实例的返回值,就传递给p的返回值。

如果Promise.all方法和Promise.race方法的参数,不是Promise实例,就会先调用下面讲到的Promise.resolve方法,将参数转为Promise实例,再进一步处理。

reslove()

不管传递什么参数,会立即返回一个状态为成功的Promise

reject()

不管传递什么参数,会立即返回一个状态为失败的Promise

特点:

  1. 对象状态不受外界影响
  2. 一旦状态改变,就不会再变,任何时候都可以得到这个结果。
    (全封闭的)一旦去启动一个Promise,外部再也不能去改变它内部的状态了

状态

pending: (进行中)初始状态,成功或失败状态。
fulfilled: 意味着操作成功完成。
rejected: 意味着操作失败。

优点

有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数(回调地狱)。
此外,Promise 对象提供统一的接口,使得控制异步操作更加容易。

缺点

1、无法取消 Promise,一旦新建它就会立即执行,无法中途取消。(全封闭)
2、如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。Promise相当于语法糖,还是需要回调函数,只不过位置改变了
3、当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。(全封闭,无法改变也无法查看)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梁什么鸭,

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值