Promise分三步
- 同步
- 异步
- 承诺
同步
class Promise{
constructor(executor){
//保存状态值
this.state='pending'
//保存——成功时传入参数
this.value=undefined
//保存——失败时原因
this.reson=undefined
//成功时更改状态,保存参数
let resolve=value=>{
if(this.state==='pending'){
this.value=value
this.state='fulfilled'
}
}
//失败时更改状态,保存失败原因
let reject=reson=>{
if(this.state==='pending'){
this.reson=reson
this.state='rejected'
}
}
try{
executor(resolve,reject)
}catch(err){
reject(err)
}
}
then(onFulfilled,onRejected){
//onFulfilled返回的是成功时的函数(例:下面pro.then的就是res => res)
//onRejected返回的是失败时的函数(例:下面pro.then的就是res => res)
if(this.state==='fulfilled'){
onFulfilled(this.value)
}
if(this.state==='rejected'){
onRejected(this.reson)
}
if(this.state==='pending'){
}
}
}
let pro = new Promise1((resolve, reject) => resolve(2333))
pro.then(res => res)//res=2333
这样一个简单的同步Promise就完成了
异步
调用异步函数会出现问题
let pro = new Promise1((resolve, reject) => {
setTimeout(res => {
resolve(res)
}, 0, 1000)
})
pro.then(res => res)//res是undefined
在Promise1中执行函数使用了异步函数(这里有栈和队列的问题)
阅览器执行顺数是同步->微任务->宏任务),在这里then中执行是同步的(实际上then中是微任务)
所以pro.then(res => res),会优先于resolve执行。执行then时状态(state)和参数(value)都没有改变
class Promise{
constructor(executor){
//保存状态值
this.state='pending'
//保存——成功时传入参数
this.value=undefined
//保存——失败时原因
this.reson=undefined
//用于保存成功异步时的执行函数
this.onFulfillCallbacks=[]
//用于失败成功异步时的执行函数
this.onRejectCallbacks=[]
//成功时更改状态,保存参数
let resolve=value=>{
if(this.state==='pending'){
this.value=value
this.state='fulfilled'
this.onFulfillCallbacks.forEach(fn => fn())
}
}
//失败时更改状态,保存失败原因
let reject=reson=>{
if(this.state==='pending'){
this.reson=reson
this.state='rejected'
this.onRejectCallbacks.forEach(fn => fn())
}
}
try{
executor(resolve,reject)
}catch(err){
reject(err)
}
}
then(onFulfilled,onRejected){
//onFulfilled返回的是成功时的函数(例:下面pro.then的就是res => res)
//onRejected返回的是失败时的函数(例:下面pro.then的就是res => res)
if(this.state==='fulfilled'){
onFulfilled(this.value)
}
if(this.state==='rejected'){
onRejected(this.reson)
}
if(this.state==='pending'){
this.onFulfillCallbacks.push(() => onFulfilled(this.value))
this.onRejectCallbacks.push(() => onRejected(this.reson))
}
}
}
这样就完成promise的异步调用了。
先看一下同步、异步的执行顺序
let pro1 = new Promise1((resolve, reject) => resolve(res) )
pro1.then(res => res)//res=2333
同步执行顺序:
constructor=>resolve=>
- 改变state状态为'fulfilled'
- 保存value传值
then=>
- 进入'fulfilled'状态
- 执行then的回调函数
let pro2 = new Promise1((resolve, reject) => {
setTimeout(res => {
resolve(res)
}, 0, 2333)
})
pro2.then(res => res)//res=2333
异步执行顺序:
constructor=>
- 因异步原因,未执行任何操作
then=>
- 进入'pending'状态
- 保存onFulfillCallbacks与onRejectCallbacks所有的回调函数并传参
resolve=>
- 异步结束,执行resolve
- 改变state状态为'fulfilled'
- 保存value传值
- 执行onFulfillCallbacks中的所有函数
承诺
promise有链式调用: pro2.then(res => res) .then(res => res) .then(res => res)
class Promise {
constructor(executor) {
this.state = "pending";
this.value = undefined;
this.reson = undefined;
this.onFulfillCallbacks = [];
this.onRejectCallbacks = [];
let resolve = value => {
if (this.state === "pending") {
this.value = value;
this.state = "fulfilled";
this.onFulfillCallbacks.forEach(fn => fn());
}
};
let reject = reson => {
if (this.state === "pending") {
this.value = reson;
this.state = "fulfilled";
this.onRejectCallbacks .forEach(fn => fn());
}
};
executor(resolve, reject);
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : value => value;
onRejected = typeof onRejected === "function" ? onRejected : err => { throw err; };
let promise2 = new Promise((resolve, reject) => {
if (this.state === "fulfilled") {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvepromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
}
if (this.state === "rejected") {
setTimeout(() => {
try {
let x = onRejected(this.reson);
resolvepromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
}
if (this.state === "pending") {
this.onFulfillCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvepromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
this.onRejectCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reson);
resolvepromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
}
});
return promise2;
}
}
constructor中没有什么变化
主要是then中有一些
1, 这里onFulfilled和onRejected做一下传值处理,只接受function(函数),不是就直接使用默认的函数。
避免不传或奇怪的传参出现问题。
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : value => value;
onRejected = typeof onRejected === "function" ? onRejected : err => { throw err; };
2, 使用Promise并return值
let promise2 = new Promise((resolve, reject) => {
})
return promise2;
//Promise链式调用后面的res传参都是前一个return返回的参数
new Promise((resolve, reject) => resolve(1))
.then(res=>res+1) //res=1
.then(res=>res+1) //res=2
.then(res=>res+1) //res=3
3,这里使用setTimeout,因为then返回是异步函数(不过setTimeout是宏任务,你们可以自己试试怎么实现微任务)
使用try catch来获取错误
关键就是resolvepromise,这是实现承诺的关键函数
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvepromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
resolvepromise
- promise2:then中已promise返回,主要查看onFulfilled和onRejected是否有执行的函数
- x:当前then的返回值,没有就是undefined
- resolve和reject就是constructor中的执行函数
function resolvepromise(promise2, x, resolve, reject) {
//promise2与x指向同一对象,已typeerror为拒因拒绝执行
if (promise2 === x) {
return reject(new TypeError("..."));
}
//当x为函数或对象时执行,否则已x为拒因拒绝执行
if (x != null && (typeof x === "function" || typeof x === "object")) {
let called;//promise中resolve和reject只执行一个
try {
let then = x.then;
//如果x.then是函数,将x作为函数的作用域调用
if (typeof then === "function") {
then.call(x,
y => {
if (called) return;
called = true;
resolvepromise(promise2, y, resolve, reject);
},
e => {
if (called) return;
called = true;
reject(error);
}
);
} else {
//如果x是对象,已x为值执行promise
resolve(x);
}
} catch (error) {
//如果x.then抛出异常e,则以e为拒因拒绝执行
if (called) return;
called = true;
reject(error);
}
} else {
resolve(x);
}
}
这里详细列一下resolvepromise的关键点,自己写的时候可以根据关键点去记
- 拒绝执行就是执行reject
- 执行就是执行resolve
1, x与Promise相等
- 如果x与Promise指向同一对象,已TypeError为拒因拒绝执行
2,x为Promise(x != null && (typeof x === "function" || typeof x === "object"))这里
- x处于等待状态'pending',promise保存等待直至x被执行或拒绝
- x处于执行状态'fulfilled',执行promise
- x处于拒绝状态'rejected',拒因promise
3,x为对象或函数
- 把x.then赋值给then
- 如果x.then抛出异常e,则以e为拒因拒绝执行
- 如果x是函数,将x作为函数的作用域调用
- 如果x是对象,已x为值执行promise
好了,这样基本的Promise就完成了
class Promise {
constructor(executor) {
this.state = "pending";
this.value = undefined;
this.reson = undefined;
this.onFulfillCallbacks = [];
this.onRejectCallbacks = [];
let resolve = value => {
if (this.state === "pending") {
this.value = value;
this.state = "fulfilled";
this.onFulfillCallbacks.forEach(fn => fn());
}
};
let reject = reson => {
if (this.state === "pending") {
this.value = reson;
this.state = "fulfilled";
this.onRejectCallbacks .forEach(fn => fn());
}
};
executor(resolve, reject);
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : value => value;
onRejected = typeof onRejected === "function" ? onRejected : err => { throw err; };
let promise2 = new Promise((resolve, reject) => {
if (this.state === "fulfilled") {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvepromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
}
if (this.state === "rejected") {
setTimeout(() => {
try {
let x = onRejected(this.reson);
resolvepromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
}
if (this.state === "pending") {
this.onFulfillCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvepromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
this.onRejectCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reson);
resolvepromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
}
});
return promise2;
}
}
function resolvepromise(promise2, x, resolve, reject) {
//promise2与x指向同一对象,已typeerror为拒因拒绝执行
if (promise2 === x) {
return reject(new TypeError("..."));
}
//当x为函数或对象时执行,否则已x为拒因拒绝执行
if (x != null && (typeof x === "function" || typeof x === "object")) {
let called;//promise中resolve和reject只执行一个
try {
let then = x.then;
//如果x.then是函数,将x作为函数的作用域调用
if (typeof then === "function") {
then.call(x,
y => {
if (called) return;
called = true;
resolvepromise(promise2, y, resolve, reject);
},
e => {
if (called) return;
called = true;
reject(error);
}
);
} else {
//如果x是对象,已x为值执行promise
resolve(x);
}
} catch (error) {
//如果x.then抛出异常e,则以e为拒因拒绝执行
if (called) return;
called = true;
reject(error);
}
} else {
resolve(x);
}
}
最后在写一点Promise的一些方法吧
1,Promise.resolve
Promise.resolve = function (val) {
return new Promise((resolve, reject) => {
resolve(val);
});
};
2,Promise.reject
Promise.resolve = function (val) {
return new Promise((resolve, reject) => {
resolve(val);
});
};
3,Promise.catch
Promise.catch=function(fn){
return this.reject(null,fn)
}
4,Promise.race
Promise.race=function(promises){
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(resolve, reject);
}
});
}
5,Promise.all
Promise.all = function (promises) {
let arr = [];
let i = 0;
let processData=function(index, data) {
arr[index] = data;
i++;
if (i == promises.length) {
resolve(arr);
}
}
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(data => {
processData(i, data);
}, reject);
}
});
};
好了,没了
给个三连吧哐哐哐,gkd