自定义Promise
简单版
function Promise(executor){
this.PromiseState = 'pending';
this.PromiseResult = null;
this.callbacks = [],
const self = this;
function resolve(data){
if(self.PromiseState !== 'pending') return ;
this.PromiseState = 'fullfilled';
this.PromiseResult = data;
setTimeout(() => {
self.callbacks.forEach(item => {
item.onResolved(data);
})
})
}
function reject(data){
if(self.PromiseState !== 'rejected') return ;
this.PromiseState = 'rejected';
this.PromiseResult = data;
setTimeout(() => {
self.callbacks.forEach(item => {
item.onRejected(data);
})
})
}
try{
executor(resolve,reject);
}catch(e){
reject(e);
}
}
Promise.prototype.then = function((onResolved,onRejected) => {
const self = this;
if(typeof onRejected !== 'function'){
onRejected = reason => {
throw reason
}
}
if(typeof onResolved !== 'function'){
onResolved = value => value;
}
return new Promise((resolve,reject)=>{
function callback(type){
try{
let result = type(self.PromiseResult);
if(result instanceof Promise){
result.then(v => {
resolve(v);
},r => {
reject(r);
})
}else {
resolve(result)
}
}catch(e){
reject(e);
}
}
if(this.PromiseState === 'fullfilled'){
setTimeout(() => {
callback(onResolved)
})
}
if(this.PromiseState === 'rejected'){
setTimeout(() => {
callback(onRejected)
})
}
if(this.PromiseState === 'pending'){
this.callbacks.push({
onResolved:function(){
callback(onResolved)
},
onRejected:function(){
callback(onRejected)
},
})
}
})
})
Promise.prototype.catch = function(onRejected){
return this.then(undefined,onRejected);
}
Promise.resolve = function(value){
return new Promise((resolve,reject) => {
if(value instanceof Promise){
value.then(v => {
resolve(v);
},r => {
reject(r);
})
}else {
resolve(value);
}
}
}
Promise.reject = function (error){
return new Promise((resolve,reject) => {
reject(error);
})
}
Promise.all = function(promises){
return new Promise((resolve,reject) => {
let count = 0;
let arr = [];
for(let i = 0; i<promises.length; i++){
promises[i].then(v => {
count++;
arr[i] = v;
if(count === promises.length){
resolve(arr);
}
},r=>{
reject(r)
})
}
});
}
Promise.race = function(promise){
return new Promise((resolve,reject) => {
for(let i = 0; i<promises.length; i++){
promises[i].then(v => {
resolve(v);
},r => {
reject(r);
})
}
})
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<script src="./promise.js"></script>
<body>
<script>
let p = new Promise((resolve,reject) => {
resolve('ok');
});
p.then(value => {
console.log(value)
},error => {
console.log(error)
})
</script>
</body>
</html>
将promise.js封装成类class
class Promise{
constructor(executor){
this.PromiseState = 'pending';
this.PromiseResult = null;
this.callbacks = [],
const self = this;
function resolve(data){
if(self.PromiseState !== 'pending') return ;
this.PromiseState = 'fullfilled';
this.PromiseResult = data;
setTimeout(() => {
self.callbacks.forEach(item => {
item.onResolved(data);
})
})
}
function reject(data){
if(self.PromiseState !== 'rejected') return ;
this.PromiseState = 'rejected';
this.PromiseResult = data;
setTimeout(() => {
self.callbacks.forEach(item => {
item.onRejected(data);
})
})
}
try{
executor(resolve,reject);
}catch(e){
reject(e);
}
}
then(onResolved,onRejected){
const self = this;
if(typeof onRejected !== 'function'){
onRejected = reason => {
throw reason
}
}
if(typeof onResolved !== 'function'){
onResolved = value => value;
}
return new Promise((resolve,reject)=>{
function callback(type){
try{
let result = type(self.PromiseResult);
if(result instanceof Promise){
result.then(v => {
resolve(v);
},r => {
reject(r);
})
}else {
resolve(result)
}
}catch(e){
reject(e);
}
}
if(this.PromiseState === 'fullfilled'){
setTimeout(() => {
callback(onResolved)
})
}
if(this.PromiseState === 'rejected'){
setTimeout(() => {
callback(onRejected)
})
}
if(this.PromiseState === 'pending'){
this.callbacks.push({
onResolved:function(){
callback(onResolved)
},
onRejected:function(){
callback(onRejected)
},
})
}
})
}
catch(onRejected){
return this.then(undefined,onRejected);
}
static resolve(value){
return new Promise((resolve,reject) => {
if(value instanceof Promise){
value.then(v => {
resolve(v);
},r => {
reject(r);
})
}else {
resolve(value);
}
}
}
static reject(error){
return new Promise((resolve,reject) => {
reject(error);
})
}
static all(promises){
return new Promise((resolve,reject) => {
let count = 0;
let arr = [];
for(let i = 0; i<promises.length; i++){
promises[i].then(v => {
count++;
arr[i] = v;
if(count === promises.length){
resolve(arr);
}
},r=>{
reject(r)
})
}
});
}
static race (promise){
return new Promise((resolve,reject) => {
for(let i = 0; i<promises.length; i++){
promises[i].then(v => {
resolve(v);
},r => {
reject(r);
})
}
})
}
}
复杂版
class MyPromise {
constructor(executor) {
this.status = 'pending';
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
try {
executor(this.resolve.bind(this), this.reject.bind(this));
} catch (error) {
this.reject(error);
}
}
resolve(value) {
if (this.status === 'pending') {
this.status = 'fulfilled';
this.value = value;
while (this.onResolvedCallbacks.length) {
const callback = this.onResolvedCallbacks.shift();
callback(this.value);
}
}
}
reject(reason) {
if (this.status === 'pending') {
this.status = 'rejected';
this.reason = reason;
while (this.onRejectedCallbacks.length) {
const callback = this.onRejectedCallbacks.shift();
callback(this.reason);
}
}
}
then(onResolved, onRejected) {
onResolved = typeof onResolved === 'function' ? onResolved : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
const promise2 = new MyPromise((resolve, reject) => {
if (this.status === 'fulfilled') {
setTimeout(() => {
try {
const x = onResolved(this.value);
this._resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
});
} else if (this.status === 'rejected') {
setTimeout(() => {
try {
const x = onRejected(this.reason);
this._resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
});
}
else {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onResolved(this.value);
this._resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
});
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
this._resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
});
});
}
});
return promise2;
}
_resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
reject(new TypeError('Chaining cycle detected'));
}
if (x instanceof MyPromise) {
x.then(
value => this._resolvePromise(promise2, value, resolve, reject),
reason => reject(reason)
);
}
else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
let called = false;
try {
const then = x.then;
if (typeof then === 'function') {
then.call(x,
value => {
if (called) return;
called = true;
this._resolvePromise(promise2, value, resolve, reject);
},
reason => {
if (called) return;
called = true;
reject(reason);
}
);
} else {
resolve(x);
}
} catch (error) {
if (called) return;
called = true;
reject(error);
}
}
else {
resolve(x);
}
}
catch(onRejected) {
return this.then(null, onRejected);
}
finally(onFinally) {
return this.then(
value => MyPromise.resolve(onFinally()).then(() => value),
reason => MyPromise.resolve(onFinally()).then(() => { throw reason })
);
}
static resolve(value) {
if (value instanceof MyPromise) {
return value;
}
return new MyPromise(resolve => resolve(value));
}
static reject(reason) {
return new MyPromise((resolve, reject) => reject(reason));
}
static all(promises) {
return new MyPromise((resolve, reject) => {
const results = [];
let count = 0;
function collectResult(index, value) {
results[index] = value;
count++;
if (count === promises.length) {
resolve(results);
}
}
promises.forEach((promise, index) => {
promise.then(
value => collectResult(index, value),
reason => reject(reason)
);
});
});
}
static race(promises) {
return new MyPromise((resolve, reject) => {
promises.forEach(promise => {
promise.then(resolve, reject);
});
});
}
static any(promises) {
return new MyPromise((resolve, reject) => {
let count = promises.length;
const reasons = [];
promises.forEach((promise, index) => {
promise.then(
value => resolve(value),
reason => {
reasons[index] = reason;
count--;
if (count === 0) {
reject(reasons);
}
}
);
});
});
}
}
let promise = new MyPromise((resolve, reject) => {
if (3 > 4) {
resolve("yes")
} else {
reject("no")
}
})
promise.then((resolve) => { console.log(resolve); }, (reject) => { console.log(reject); })