/**
* 实现一个Promise
*/
function Promise(task) {
//接收一个处理函数
let that = this;//缓存this
//promise有三种状态 默认为pending
that.status = 'pending';
that.onFulfilledFns = [];//所有成功的回调
that.onRejectedFns = [];//所有失败的回调
that.value = undefined;
function resolve(value) {
if (that.status == 'pending') {
that.status = 'fulfilled';
that.value = value;
that.onFulfilledFns.forEach(item => item(value));
}
};
function reject(reason) {
if (that.status == 'pending') {
that.status = 'rejected';
that.value = reason;
that.onRejectedFns.forEach(item => item(reason));
}
};
//立即执行传入的处理函数
try {
task(resolve, reject);
} catch (err) {
reject(err)
}
};
function resolvePromise(promise2, x, resolve, reject) {
let then;
if (promise2 === x) {
return reject(new Error('循环引用'));
}
if (x instanceof Promise) {
//判断x的prototype所指向的对象是否存在Promise的原型链上
if (x.status = 'pending') {
x.then(function (y) {
//递归 调用
resolvePromise(promise2, y, resolve, reject);
}, reject)
} else if (x.status == 'fulfilled') {
resolve(x.value);
} else if (x.status == 'rejected') {
reject(x.value);
}
} else if (x != null && typeof x == 'object' || typeof x == 'function') {
try {
then = x.then;
if (typeof then == 'function') {
then.call(x, function (y) {
resolvePromise(promise2, y, resolve, reject);
}, function (y) {
reject(y)
});
}
} catch (e) {
reject(e);
}
} else {
resolve(x);
}
}
//then方法
Promise.prototype.then = function (onFulfilled, onRejected) {
//假如没有传入异步处理程序则直接返回结果
onFulfilled = typeof onFulfilled == 'function' ? onFulfilled : function (value) {
return value;
};
onRejected = typeof onRejected == 'function' ? onRejected : function (reason) {
return reason;
};
var promise2;//用来实现链式调用
let that = this;
if (that.status == 'fulfilled') {
promise2 = new Promise(function (resolve, reject) {
let x = onFulfilled(that.value);
resolvePromise(promise2, x, resolve, reject);
});
} else if (that.status == 'rejected') {
promise2 = new Promise(function (resolve, reject) {
let x = onRejected(that.value);
reject(x);
});
} else if (that.status == 'pending') {
promise2 = new Promise(function (resolve, reject) {
that.onFulfilledFns.push(function () {
let x = onFulfilled(that.value);
resolve(x);
});
that.onRejectedFns.push(function () {
let x = onRejected(that.value);
reject(x);
});
});
} else {
promise2 = new Promise(function (resolve, reject) {
reject('Promise内部状态错误');
});
}
return promise2;
};
Promise.resolve = function (val) {
return new Promise(function (resolve, reject) {
resolve(val);
});
};
Promise.reject = function (val) {
return new Promise(function (resolve, reject) {
reject(val);
});
};
Promise.all = function (arrs) {
//all方法接收一个promise数组,数组中所有异步操作结束后返回一个新的promise
if (typeof arrs == 'object' && arrs.length > 0) {
return new Promise(function (resolve, reject) {
let result = [];//新的promise返回结果
let indexNum = 0;//当前完成几个
let resolved = function (index) {
return function (data) {
result[index] = data;
indexNum++;
if (indexNum == arrs.length) {
resolve(result);
}
}
};
for (let i = 0; i < arrs[i].length; i++)
arrs[i].then(resolved(i), function (reason) {
reject(reason);
});
});
} else {
return new Promise(function (resolve, reject) {
reject(new Error('all方法传入参数错误'));
});
}
};
Promise.race = function (arrs) {
if (typeof arrs == 'object' && arrs.length > 0) {
return new Promise(function (resolve, reject) {
for (let i = 0; i < arrs[i].length; i++)
arrs[i].then(function (data) {
resolve(data);
}, function (err) {
reject(err);
});
});
} else {
return new Promise(function (resolve, reject) {
reject(new Error('race方法传入参数错误'));
})
};
};
//test
var promise = new Promise((resolve, reject) => {
resolve(123)
})
promise.then((res) => {
console.log(res + 100);
return res + 100;
}).then((res) => {
console.log(res)
})
promise的三个缺点
1,无法取消promise,一旦新建它就会立即执行,无法中途取消
2,如果不设置回调函数,promise 内部抛出的错误,不会反映到外部
3,当处于 pending 状态时,无法得知目前进展到了哪一个阶段,是刚刚开始还是即将完成
另一个版本的Promise(推荐)
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
function Promise(executor) {
let self = this
// 初始化
self.status = PENDING
// 定义回调
self.onResolvedCallbacks = []
self.onRejectedCallbacks = []
function resolve(value) {
if (value != null && value.then && typeof value.then === 'function') {
return value.then(resolve, reject)
}
// 如果是初始状态.则改变成成功状态
setTimeout(() => {
if (self.status === PENDING) {
self.status = FULFILLED
self.value = value
// 调用所有的成功
self.onResolvedCallbacks.forEach(cb => cb(self.value))
}
})
}
function reject(reason) {
setTimeout(() => {
if (self.status === PENDING) {
self.status = REJECTED
self.value = reason
self.onRejectedCallbacks.forEach(cb => cb(self.value))
}
})
}
try {
// 捕获函数执行时出现的异常
executor(resolve, reject)
} catch(e) {
reject(e)
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('循环引用'))
}
let called = false
if (x instanceof Promise) {
if (x.status === PENDING) {
x.then(function(y){
resolvePromise(promise2, y, resolve, reject)
}, reject)
} else {
x.then(resolve, reject)
}
} else if(x != null && ((typeof x === 'object') || (typeof x.then === 'function'))) {
// 兼容性处理
consoole.log('兼容性处理')
try {
let then = x.then
if (typeof then === 'function') {
then.call(x, (y) => {
if (called) return
called = true
resolvePromise(promise2, y, resolve, reject)
}, (err) => {
if (called) return
called = true
reject(err)
})
} else {
resolve(x)
}
} catch(e) {
if (called) return
called = true
reject(e)
}
} else {
// x是一个普通的值
resolve(x)
}
}
Promise.prototype.then = function(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(value) {return value}
onRejected = typeof onRejected === 'function' ? onRejected : function(reason) {throw reason}
let self = this
let promise2
if (self.status == FULFILLED) {
return promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
try {
let x = onFulfilled(self.value);
//如果获取到了返回值x,会走解析Promise的过程
resolvePromise(promise2, x, resolve, reject);
} catch(e) {
//如果执行成功的回调过程中出错了,用错误原因把Promise2 reject
reject(e);
}
})
})
}
if (self.status == REJECTED) {
return promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
try {
let x = onRejected(self.value);
resolvePromise(promise2, x, resolve, reject);
} catch(e) {
reject(e);
}
})
})
}
if(self.status == PENDING){
return promise2 = new Promise(function(resolve,reject){
self.onResolvedCallbacks.push(function(){
try{
let x =onFulfilled(self.value);
//如果获取到了返回值x,会走解析promise的过程
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
});
self.onRejectedCallbacks.push(function(){
try{
let x =onRejected(self.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
});
});
}
}
Promise.prototype.catch = function(onRejected) {
this.then(null, onRejected)
}
Promise.race = function(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(resolve, reject)
}
})
}
Promise.deferred = Promise.defer = function(){
let defer = {};
defer.promise = new Promise((resolve,reject) => {
defer.resolve = resolve;
defer.reject = reject;
});
return defer;
}
Promise.resolve = function (value) {
return new Promise((resolve, reject) => resolve(value))
}
Promise.reject = function (reason) {
return new Promise((resolve, reject) => reject(reason))
}
Promise.all = function (promises) {
return new Promise((resolve, reject) => {
let done = gen(promises.length, resolve)
for (let i = 0; i < promises.length; i++) {
promises[i].then(val => {
done(i, val)
}, reject)
}
})
}
function gen(i, val) {
let count = 0, result = []
return function (i, val) {
result[i] = val
if (++count === i) {
resolve(result)
}
}
}
module.exports = Promise
网友评论