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
这篇博文里的评论。