promise
用法分析
流程分析
- promise通过一个接收一个函数进行实例化
- 此函数接收两个参数,一个为fulfill时进行的处理,一个为reject时进行的处理
- 当exector函数在promise内部进行执行时,修改promise的value和status
- 在then和catch中,根据status进行条件判断
关于优化的点
- exector为异步调用时
- 如何实现then的链式调用
代码基本实现
-
promise接收一个exector,并在内部进行value和status的改变
-
then进行resolve的实现
-
catch进行reject的实现
代码优化
关于异步
当出现异步操作时,即promise先对exector内部逻辑进行事件注册,然后对then和catch进行执行,当exector内部需要执行时再进行执行,也即需要先对then和catch对应的事件进行保留,再根据exector的改变进行调用
-
在promise内声明两个操作数组
-
在then中加入pending状态下,将操作事件压入的分支
-
在promise中当status改变时,对操作数组内的事件进行执行
关于链式操作
-
链式操作的关键在于在操作时,返回一个promise
-
promise的exector函数,为对当前then传入的fulfulled和rejected函数的处理
" -
promise的value和status值,为上一步即fulfulled和rejected的返回值
-
如果返回值为非promise类型,则通过resolve状态改变函数,将此返回值作为参数传入
-
如果返回值为promise类型,则通过x.then(resolve,reject) 对其内部的值进行改变(由于resolve和reject的this都对应着返回值promise,x内部的操作即对返回promise的value和status的改变)
-
如果出现错误,则也将其作为下一个promise的成功resolve的参数进行传递
-
代码
function promise( exector ) {
let _this = this;
this.value = null; // 处理值
this.status = 'pending'; //当前状态
this.reason = null; // 失败原因
this.onFulfilledCallback = []; // resolve处理数组
this.onRejectCallback = []; // reject处理数组
//当且仅当 status为pending时 状态才可以改变 即一旦成功或失败 则不允许改变状态
//resolve函数 改变value 改变状态
function resolve( value ) {
if (_this.status == 'pending') {
_this.value = value;
_this.status = 'resolve';
_this.onFulfilledCallback.forEach(fn => {
fn(_this.value); // 根据函数注册的顺序执行
});
}
}
// reject函数 改变reason 改变状态
function reject( reason ) {
if (_this.status == 'pending') {
_this.reason = reason;
_this.status = 'reject';
_this.onRejectCallback.forEach(fn => {
fn(_this.reason);
});
}
}
try {
exector(resolve, reject); //执行 进行状态的改变
} catch ( e ) {
reject(e); // 直接跳到reject状态
}
}
promise.prototype.then = function ( onFulfilled, onRejected ) {
let _this = this;
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function ( value ) { }; // 判断是否为函数
onRejected = typeof onRejected === 'function' ? onRejected : function ( reason ) { };
if (_this.status == 'resolve') {
return new promise(( resolve, reject ) => {
try {
let x = onFulfilled(_this.value);//处理这一步的操作
if( x instanceof promise){ //但当前返回值为promise时
x.then(resolve,reject);
//因为resolve和reject都指向外部this,所以在x中改变value和status即对外部进行改变
}
else{
resolve(x); // 改变返回promise的value和status
}
}
catch ( e ) {
reject(e);
}
});
}
if (_this.status == 'reject') {
return new promise(( resolve, reject ) => {
try {
let x =onRejected(_this.value);
if(x instanceof promise){
x.then(resolve,reject);
}
else{
resolve(x);
}
}
catch ( e ) {
reject(e);
}
});
}
if (_this.status == 'pending') {
return new promise(( resolve, reject ) => {
_this.onFulfilledCallback.push(() =>{
let x = onFulfilled(_this.value);
if( x instanceof promise){
x.then(resolve,reject);
}else{
resolve(x);
}
});
_this.onRejectCallback.push( () =>{
let x = onRejected(_this.reason);
if(x instanceof promise){
x.then(resolve,reject);
}else{
resolve(x);
}
});
});
}
};
promise.prototype.catch = function ( error ) {
return this.then(null, error);
};
function test( resolve, reject ) {
let i = Math.random() * 10;
setTimeout(function () {
if (i > 5) {
resolve(i);
} else {
reject(i);
}
;
}, 500);
console.log('123456');
}
function test2( x ) {
let i = Math.random() * 100;
return new promise(function ( resolve,reject ) {
console.log("略略略"+x);
resolve(x+1);
});
}
let p = new promise(test);
// p.then(function ( value ) {
// console.log('resolve' + value);
// return " resolve"+value;
// },function ( error ) {
// console.log('error' + error);
// return " error"+error;
// }).then(function ( value ) {
// console.log('resolve' + value);
// }).catch(function ( error ) {
// console.log('error' + error);
// });
p.then(test2).then(test2);