promise是为了解决回调地狱所加入的语法,虽然他也存在部分问题 1.延时问题2.promise一旦创建,无法取消3.pending状态的时候,无法得知进展到哪一步(比如接口超时,可以借助race方法)4.promise会吞掉内部抛出的错误,不会反映到外部。如果最后一个then方法里出现错误,无法发现。(可以采取hack形式,在promise构造函数中判断onRejectedCb的数组长度,如果为0,就是没有注册回调,这个时候就抛出错误,某些库实现done方法,它不会返回一个promise对象,且在done()中未经处理的异常不会被promise实例所捕获)5.then方法每次调用都会创建一个新的promise对象,一定程度上造成了内存的浪费 我们先看看他的平常用法。
const promise = new Promise((resolve, reject) => {
if(true) {
resolve('success')
} else {
reject('error')
}
})
promise.then(value => {
console.log(value)
}, reason => {
console.log(reason)
}).then(value=> {
console.log('value ' + value)
}, error => {
console.log('error ' + error)
})
链式操作 先写一个promise方法
class myPormise {
// 这里的executor是我们传入的一个函数, 这个函数需要立即执行
constructor(executor) {
this.value = null
// 这里有可能执行时报错,我们需要把所有的错误都交给reject处理
try {
// 我们需要传入两个函数进去,因为会因为调用位置的变化,所以我们需要绑定一下this
executor(this.resolve.bind(this), this.reject.bind(this))
} catch(e) {
this.reject(e)
}
}
resolve(value) {
this.value = value
}
reject(reason) {
this.value = reason
}
}
这个是终极版,有回调,有参数。
/*
手写一个promise
*/
function normalUse(Pro) {
const Con = Pro || Promise;
const promise = new Con((resolve, reject) => {
const num = Math.random() * 10;
if (num > 5) {
resolve(num);
} else {
reject(num);
}
});
promise
.then(
(value) => {
console.log("success", value);
},
(reason) => {
console.log("fail", reason);
}
)
.then(
(value) => {
console.log("value " + value);
},
(error) => {
console.log("error " + error);
}
);
}
const PENDING = "pending";
const FULLFILLED = "fullfilled";
const REJECT = "reject";
class MyPromise {
constructor(executor) {
// 执行函数,执行函数可以使用resolve reject
this.executor = executor;
}
then(onFulfilled, onRejected) {
this.onFulfilled = onFulfilled;
this.onRejected = onRejected;
}
}
var index = 2;
// 复杂的,全面的promise
class AllPromise {
constructor(callback, name) {
this.name = name; // 加一个promiseName
this.callback = callback;
this.value = undefined;
this.error = undefined;
this.status = PENDING;
this.onResCallbacks = [];
this.onFailCallbacks = [];
const resolve = (value) => {
console.log("r promiseName", this.name, this.onResCallbacks.length);
this.status = FULLFILLED;
this.value = value;
this.onResCallbacks.forEach((cb) => cb(value));
};
const reject = (erorr) => {
console.log("e promiseName", this.name);
if (this.status === PENDING) {
this.status = REJECT;
this.error = erorr;
this.onFailCallbacks.forEach((cb) => cb(erorr));
}
};
callback(resolve, reject); // 扔出两个函数(失败和成功,供调用)
}
then(onFulfilled, onRejected) {
// then的第二个参数(onRejected)可以当做catch,如果执行了的话,那么后面跟着的catch就不会执行
// 当然,then中任何报错都会走到后面的catch中。
console.log("onFulfilled", onFulfilled, this.name);
onFulfilled =
typeof onFulfilled === "function" ? onFulfilled : (value) => value;
onRejected =
typeof onRejected === "function" ? onRejected : (error) => error;
const pr1 = new AllPromise((resolve, reject) => {
if (this.status === FULLFILLED) {
console.log("fullfilled", this.name);
try {
const x = onFulfilled(this.value);
resolve(x);
} catch (error) {
reject(error);
}
} else if (this.status === REJECT) {
console.log("reject", this.name);
try {
const x = onRejected(this.error);
resolve(x);
} catch (error) {
reject(error);
}
} else if (this.status === PENDING) {
console.log("PENDING,堆栈", this.name);
// 这里就是堆栈,把链式操作堆在后面。
// promise值给下一个promise(then),子的执行函数往父上堆。
this.onResCallbacks.push(() => {
if (this.status === FULLFILLED) {
try {
const x = onFulfilled(this.value);
console.log("执行结果", x, this.name);
resolve(x);
} catch (error) {
reject(error);
}
}
});
// 需要注意的是,这里的fail也要对入栈。yehji
this.onFailCallbacks.push(() => {
try {
const x = onRejected(this.value);
resolve(x);
} catch (error) {
reject(error);
}
});
} else {
this.onResCallbacks = [];
this.onFailCallbacks = [];
}
}, `promise${index++}`);
return pr1;
}
catch(onRejected) {
return this.then(null, onRejected);
}
}
const promise = new AllPromise((resolve, reject) => {
setTimeout(() => {
console.log("timeout");
resolve("成功");
}, 1000);
}, "promise1");
promise
.then(1111111)
.then((value) => {
console.log("2");
// return "第一次"
setTimeout(() => {
console.log("55555");
return "第一次";
}, 1000);
})
.then((value) => {
console.log("3");
return new AllPromise((resolve, reject) => {
setTimeout(() => {
resolve("第二次处理结果");
}, 1000);
}, "end Promise");
})
.then((value) => {
console.log(value);
throw new Error("抛出异常");
})
.catch((error) => {
console.log(error);
});
每次then都是一个promise。 参考:简单实现一个promise 手动实现promise