Promise对象用于表示一个异步操作的最终状态以及操作的值。Promise本质上是一个绑定了回调的对象,区别于将回调传入函数内部。
我们通过构造函数去创建promise实例:
let promise = new Promise( function(resolve, reject) {...} /* executor */ );
Promise构造函数传入一个参数executor函数,executor是带有resolve和reject两个参数的函数。在构造函数返回Promise实例对象前executor被调用,当前状态被初始化成pedding状态,executor内部执行一些异步操作,当异步操作执行完毕根据执行情况:当成功执行则调用resolve函数将promise状态更新为fulfilled,否则执行reject函数设置promise状态为rejected。
一个Promise只有三种状态:
a. Promise方法
方法 | 描述 |
---|---|
Promise.reject(reason) | 返回一个Promise对象,状态设置为失败并传递失败原因给处理函数 |
Promise.resolve(value) | 返回一个promise对象,能够将value以Promise是形式使用 |
Promise.all(iterable) | iterable 是一个数组对象,只有当iterable每个promise对象都成功执行才会触发,返回一个数组对象保存promise对象数组的执行结果,和iterable每个对象的顺序保持一致 |
Promise.race(iterable) | 返回一个Promise,按照iterable数组任意promise对象最先执行完毕的结果立即返回,成功执行返回执行结果还是失败返回原因 |
b. 构造函数
构造函数 | 描述 |
---|---|
| 通过new关键字创建实例对象,resoleve是异步函数成功执行调用,否则执行reject |
c. 原型链方法
方法 | 描述 |
---|---|
promise.then(onFulfilled, onRejected) | 当promise解析完成,则调用onFulfilled,如果promise拒绝,则执行onRejected,两个都是可选的参数 |
promise.catch | promise拒绝,等价于 promise.then(undefined, onRejected) |
我们已经整理了Promise对象的属性和方法,已经promise对象从原型链继承的属性和方法,现在我们需要一步一步自己去实现一个Promise类。
const STATE = {
PENDING: 'pending',
FULFILLED: 'fulfilled',
REJECTED: 'rejected'
}
const emptyObj = {};
function handleFun(fun, resolve, reject) {
try {
fun(resolve, reject);
} catch (err) {
reject(err);
}
}
function getFun(fun) {
return typeof fun === 'function' ? fun : function(e) {return e};
}
function PromiseFun(fu) {
if(fu === emptyObj) return;
this.defaultState = STATE.PENDING;
this.state = STATE.PENDING;
this.data = 0;
this.onFulfilledList = [];
this.onRejectedList = [];
const resolve = (val) => {
if(this.state !== STATE.PENDING) return;
this.state = STATE.PENDING;
this.data = val;
this.onFulfilledList.forEach(fun => {
fun(val);
})
}
const reject = (reason) => {
if(this.state !== STATE.PENDING) return;
this.state = STATE.REJECTED;
this.onRejectedList.forEach(fun => {
fun(reason);
})
}
handleFun(resolve, reject);
}
PromiseFun.prototype.then = function(onFulfilled, onRejected) {
let self = this;
onFulfilled = getFun(onFulfilled);
onRejected = getFun(onRejected);
switch(this.state) {
case STATE.PENDING:
let fun_pending = function(resolve, rejected) {
self.onFulfilledList.push(function(val) {
try {
let data = onFulfilled(self.data);
if(data instanceof PromiseFun) {
data.then(resolve, reject);
} else {
resolve(data);
}
} catch (err) {
reject(err);
}
})
self.onRejectedList.push(function(val) {
try {
let data = onRejected(self.data);
if(data instanceof PromiseFun) {
data.then(resolve, reject);
} else {
reject(data)
}
} catch (err) {
reject(err);
}
})
}
return new PromiseFun(fun_pending);
case STATE.FULFILLED:
let fun_fulfilled = function(resolve, reject) {
try {
let data = onFulfilled(self.data);
if(data instanceof PromiseFun) {
data.then(resolve, reject);
}else {
resolve(data);
}
} catch (err) {
reject(err);
}
}
return new PromiseFun(fun_fulfilled);
case STATE.REJECTED:
let fun_rejected = function(resolve, reject) {
try {
let data = onRejected(self.data);
if(data instanceof PromiseFun) {
data.then(resolve, reject);
}else {
reject(data);
}
} catch(err) {
reject(err);
}
}
return new PromiseFun(fun_rejected);
}
}
PromiseFun.prototype.catch = function(onRejected) {
return this.then(null, onRejected);
}
PromiseFun.resolve = function(value) {
return new PromiseFun(function(resolve, rejected) {
resolve(value);
})
}
PromiseFun.reject = function(reason) {
return new PromiseFun(function(resolve, rejected) {
rejected(reason);
})
}
PromiseFun.all = function(promiseArr) {
if(!Array.isArray(promiseArr)) return;
let len = promiseArr.length;
let count = 0;
let resultArr = [];
for(let i = 0; i < len; i++) {
let item = promiseArr[i];
PromiseFun.resolve(item).then(function(val) {
count++;
resultArr[i] = val;
if(count === len) {
return reason(resultArr);
}
}, function(reason) {
reject(reason)
})
}
}
参考
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。