promise简要介绍
promise是一种解决异步编程的解决方案,promise一个容器,里面保存着未来异步结束事件的值,promise某种意义上是一种对象结构,promise提供了很多的操作运算;如then等;
promise实现核心
1、 promise三个状态——pedding, resolve,reject; 从pedding转变为resolve; 从pedding转变为reject;状态转变了就不可逆; 2、 .then类似于一个promise的转换,管道通路;promise的一个传递和接通,核心点就是.then(上个promise的resolve,reject);就可以接通了;
实现细节
实例变量
- this.state(描述promise状态)
- this.data(描述promise异步获取到的值)
- this.resolveCallBacks(promise成功事件回调队列)
- this.rejectCallBacks的抽离;(promise失败事件回调)
原型上的方法
- then;(1、分为三种状态来处理 —— pedding,resolve,reject; 2、then返回的一个promise; 3、拿到当前promise的值包在promise里面返回)
- catch (1、就是.then(null, onReject));
静态方法:
- all (接收一个promise数组,如果是成功状态:返回一个promise包装的所有成功状态的值;如果是失败,就返回reject)
- race (接收一个promise数组, 返回最先改变的状态的某个promise)
- resolve
const PEDDING = 'pedding';
const RESOLVE = 'resolve';
const REJECT = 'reject';
class MyPromise {
constructor(fn) {
this.state = PEDDING;
this.data = null;
this.resolveCallBacks = [];
this.rejectCallBacks = [];
const resolve = (value) => {
if(this.state === PEDDING) {
this.state = RESOLVE;
this.data = value;
this.resolveCallBacks.forEach(item => {
item(value);
})
}
};
const reject = (value) => {
if(this.state === PEDDING) {
this.state = REJECT;
this.data = value;
this.rejectCallBacks.forEach(item => {
item(value);
})
}
}
try {
fn(resolve, reject);
} catch(e) {
reject(e);
}
}
then(onResolve, onReject) {
let promise = null;
onResolve = typeof onResolve === 'function' ? onResolve : () => {};
onReject = typeof onReject === 'function' ? onReject : () => {};
if(this.state === RESOLVE) {
return promise = new Promise((resolve, reject) => {
try {
const v = onResolve(this.data);
if(v instanceof Promise) {
v.then(resolve, reject);
}
resolve(this.data)
} catch(e) {
reject(e);
}
})
}
if(this.state === REJECT) {
return promise = new Promise((resolve, reject) => {
try {
const v = onReject(this.data);
if(v instanceof Promise) {
v.then(resolve, reject);
}
reject(this.data);
} catch(e) {
reject(e);
}
})
}
if(this.state === PEDDING) {
return promise = new Promise((resolve,reject) => {
this.resolveCallBacks.push((value) => {
try {
const v = onResolve(value);
if(v instanceof Promise) {
v.then(resolve, reject);
}
} catch(e) {
reject(e)
}
})
this.rejectCallBacks.push((value) => {
try {
const v = onReject(value);
if(v instanceof Promise) {
v.then(resolve, reject);
}
} catch(e) {
reject(e)
}
})
})
}
}
catch(onRejct) {
this.then(null,onRejct);
}
static resolve(value) {
return new Promise((resolve) => {
if(value instanceof Promise) {
value.then(resolve);
}
resolve(value);
})
}
static all(iterable) {
if(Array.isArray(iterable)) {
throw new Error('iterable need array');
}
return new Promise((resolve, reject) => {
let totalCount = 0;
let responseArr = [];
iterable.forEach((promise,index) => {
MyPromise.resolve(promise).then((value) => {
totalCount++;
responseArr[index] = value;
if(totalCount === iterable.length) {
resolve(responseArr);
}
}, (reason) => {
reject(reason);
})
})
})
}
static race(iterable) {
if(Array.isArray(iterable)) {
throw new Error('iterable need array');
}
return new Promise((resolve, reject) => {
iterable.forEach((promise) => {
MyPromise.resolve(promise).then(
value => {
resolve(value)
}, reason => {
reject(reason)
});
})
})
}
}