-
为什么会出现Promise?
-
传统的异步是通过回调函数来解决的,当出现多个异步的时候,就会出现很多层嵌套的回调函数。所以为了解决嵌套带来的不便,ES6统一了Promise对象的异步解决方案。
-
Promise的含义:promise是异步编程的解决方案。他存在三个状态(进行中-pending、成功-fulfilled、失败-rejected)。Promise返回一个对象,对象里保存着该异步对象的状态。
-
Promise状态的特点:
-
对象的状态不受外界的影响。Promise代表的是异步操作的对象,它的状态只能通过异步操作的结果来改变。其他任何操作都是不可以改变的。
-
一旦状态改变了,或者说一旦状态不再是进行中-pending(0),那么该状态就不会在发生任何改变。以及任何情况都不能改变该promise对象的状态。并且任何时候都可以获取到该对象的状态值。注意:状态的转换只能由 进行中-pending-->成功-fulfilled;或者由 进行中-pending-->失败-rejected。
-
源码分析,仅参考core.js;
-
状态的标识:在源码里,我们可以看到注释的States的说明。如下:
可以看到还存在状态值为3的一个标识,他翻译过来就是:采用另一个promise对象的状态。
-
创建promise对象:
-
通过**new Promise((res,rej)=>{})**的方式去创建Promise对象。源码中显示,在创建Promise对象的时候,首先会判断是否是通过new 构造函数的形式创建的Promise对象。其次会判断构造函数的参数是否是一个函数。任意一个不符合,都会抛出异常,提示开发人员如何正确的使用。
-
在上一张图片中,我们可以看到最后一行有一个函数的调用doResolve(fn, this);那这个函数是做什么用的呢?
-
在上边也一直在强调说,状态一旦改变,就不会在发生其他的改变。那doResolve(fn, this)函数就是保证该状态一旦发生变化后不会在有任何的改变。
-
在tryCallTwo的方法中,我们可以看到在创建Promise时被当做参数的函数在此tryCallTwo中被调用了,并且给予了两个参数,一个是处理resolve的函数,一个是处理reject的函数。
-
由上述源代码以及下图演示代码可以看出,我们不能只创建了Promise对象,我们还需要去调用改变状态的方法,然后才会触发状态的改变的机制。
-
-
源码中then函数
-
如何使用then函数?
-
new Promise((res)=>{console.log(1);}).then((val)=>{console.log(1);})
-
源码中怎样声明的,如下图:
-
可以发现then函数是绑定在Promise对象的原型链上了。而且是通过new Promise()构造函数创建的对象的原型链上。
-
then函数中还做了安全的then函数的处理。当前的constructor构造器不属于Promise的话,会自动创建一个该Promise实例的对象的函数。
-
通过上述的源码我们可以看出,整个代码中都采用的是self代表当前Promise实例对象,该实例对象上的所有信息也都是统一的。所以,这也就是为什么我们可以在任何时候都能获取到该对象的状态。