从外部改变promise内部状态

promise是什么?

1、主要用于异步计算
2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
3、可以在对象之间传递和操作promise,帮助我们处理队列

为什么会有promise?

为了避免界面冻结(任务)

  • 同步:假设你去了一家饭店,找个位置,叫来服务员,这个时候服务员对你说,对不起我是“同步”服务员,我要服务完这张桌子才能招呼你。那桌客人明明已经吃上了,你只是想要个菜单,这么小的动作,服务员却要你等到别人的一个大动作完成之后,才能再来招呼你,这个便是同步的问题:也就是“顺序交付的工作1234,必须按照1234的顺序完成”。

  • 异步:则是将耗时很长的A交付的工作交给系统之后,就去继续做B交付的工作,。等到系统完成了前面的工作之后,再通过回调或者事件,继续做A剩下的工作。
    AB工作的完成顺序,和交付他们的时间顺序无关,所以叫“异步”。

而官方文档则表示

Promise 对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是 Promise 这个名字的由来,它的英语意思就是「承诺」,表示其他手段无法改变。

 

但是经过实际测试从外部控制promise状态的事其实是可以办到的:

1、Promise的状态取决于promise主体中是否调用了resolved或者reject或者在调用resolved和reject前就发生异常(将会直接进入 reject状态)

2、Promise也是js对象(虽然它实际是个函数)、逃不开按地址引用带来的副作用,调用reject,但是没有设置fn的reject,或者catch,故会报错。Promise允许不设置resolved方法(即如果直接调用obj.ok()是没问题的,不会报错,promise状态也会变为resolved)、但如果出现异常或者主动调用进入reject而没有设置reject方法 或catch方法,则会报错。

具体实现代码demo

  let obj = {} // 用于保存promise里的resolve和reject方法
  let a = function(){
    let p = new Promise(function(resolve,reject){
      obj.ok = resolve;
      obj.cancel = reject;
    });
    return p;
  }
  async function test () { // 使用async/await测试效果
    console.log('test开始')
    let c = await a();
    console.log(c)
    console.log('test结束');
  }
  test()
  setTimeout(function(){
    obj.ok('哈哈哈哈哈')
  },2000)

结果为

 

 试验证明在promise外部通过地址引用的方式进行改变promise内部状态是可以实现的。

思路来源于

https://segmentfault.com/u/joey_5a961933efd3e

 

这位老哥在

https://segmentfault.com/q/1010000011145129

这篇博文里的评论。 

 

posted @ 2020-08-06 10:23  LeoX的爬坑笔记  阅读(1030)  评论(0编辑  收藏  举报