为什么用Promise?
- Promise能解决回调地狱问题
- Promise能多个异步操作并行,获取最终结果
Promise三种状态
- Pending Promise对象实例创建时候的初始状态
- Fulfilled 可以理解为成功的状态
- Rejected 可以理解为失败的状态
Promise状态转换
Promise一旦从pending状态到resolve状态或者reject状态就不会再改变,能保证结果的正确性,不会出现从成功到失败或者从失败到成功的情况。
原生Promise使用分析
let promise = new Promise((resolve,reject)=>{
resolve("xxx")
reject("sssss")
})
promise.then(res=>{
console.log("success",res);
},e=>{
console.log("fail",e);
})
Promise
创建一个Promise需要传递一个
executor
回调函数作为参数,来初始化Promise。executor
中有两个参数,一个resolve用来回调返回值或者另一个Promise,一个reject用来回调失败值或者Error。
then()
then函数需传递两个函数作为参数,一个回调resolve的结果,一个回调reject的结果
const STATUS = {
"PENDING": "pending",
"FULFILLED": "fulfilled",
"REJECTED": "rejected"
}
class Promise {
/**
* Creates a new Promise.
*
* @param executor — A callback used to initialize the promise.
* This callback is passed two arguments: a resolve callback used to resolve the promise
* with a value or the result of another promise, and a reject callback used to reject the
* promise with a provided reason or error.
*/
constructor(executor) {
this.status = STATUS.PENDING;
this.value = undefined;
this.reason = undefined;
const resolve = (value) => {
if (this.status === STATUS.PENDING) {
this.status = STATUS.FULFILLED;
this.value = value;
}
};
const reject = (reason) => {
if (this.status === STATUS.PENDING) {
this.status = STATUS.REJECTED;
this.reason = reason;
}
};
try {
executor(resolve, reject);
} catch (error) {
}
}
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled — The callback to execute when the Promise is resolved.
* @param onrejected — The callback to execute when the Promise is rejected.
* @returns — A Promise for the completion of which ever callback is executed.
*/
then(onfulfilled,onrejected) {
if(this.status === STATUS.FULFILLED){
onfulfilled(this.value)
}
if(this.status === STATUS.REJECTED){
onrejected(this.reason)
}
}
}
module.exports = Promise;
let promise = new Promise((resolve,reject)=>{
resolve("xxx")
reject("sssss")
})
promise.then(res=>{
console.log("success",res);
},e=>{
console.log("fail",e);
})
//success xxx
现在我们实现了一个简单的Promise,可以在Promise中通过resolve函数传递普通值到then函数中,并在then的onfullfilled中取出,或者通过reject传递在onrejected中取出。并且实现Promise状态从pendding到resolve或reject,不可逆。
实现链式调用
then(onfulfilled,onrejected) {
let promise2 = new Promise((resolve,reject)=>{
if(this.status === STATUS.FULFILLED){
let x = onfulfilled(this.value)
resolve(x)
}
if(this.status === STATUS.REJECTED){
let x = onrejected(this.reason)
reject(x)
}
if(this.status === STATUS.PENDING){
this.onResolvedCallbacks.push(()=>{
onfulfilled(this.value);
});
this.onrejectedCallbacks.push(()=>{
onrejected(this.reason);
});
}
});
return promise2;
}
const resolve = (value) => {
if (this.status === STATUS.PENDING) {
this.status = STATUS.FULFILLED;
this.value = value;
this.onResolvedCallbacks.forEach(fn=>fn());
}
};
const reject = (reason) => {
if (this.status === STATUS.PENDING) {
this.status = STATUS.REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach(fn=>fn());
}
};
let promise = new Promise((resolve,reject)=>{
resolve("xxx")
reject("sssss")
})
promise.then(res=>{
console.log("success",res);
return "next"
},e=>{
console.log("fail",e);
}).then(res=>{
console.log("success1",res)
})
//success xxx
//success1 next
处理返回值是Promise的情况 resolvePromise函数的实现
//解析x类型,决定promise2走成功还是失败
function resolvePromise(promise2, x, resolve, reject) {
console.log("x", x)
if (x === promise2) {
return reject(new TypeError("返回值错误,不能使用同一个promise"))
}
//只有object或者function才能是Promise
if ((typeof x === 'object' && typeof x != null) || typeof x === 'function') {
let called = false;//成功或者失败方法只能调用一次,防止其他Promise实现错误
try {
let then = x.then;//通过判断x上是否有then函数,判断x是否是一个Promise
if (typeof then === 'function') {
then.call(x, y => {
if (called) return;
called = true;
// resolve(y) y有可能还是promise 递归解析 直到是普通值为止
resolvePromise(promise2, y, resolve, reject);
}, r => {
if (called) return;
called = true;
reject(r);
})
} else {
reject(x);
}
} catch (error) {
if (called) return;
called = true;
reject(error);
}
} else {
reject(x);
}
}
引入Promise A+ 单元测试
Promise.deferred = function () {
let dfd = {};
dfd.promise = new Promise((resolve, reject) => {
dfd.resolve = resolve;
dfd.reject = reject;
})
return dfd;
}
npm install promises-aplus-tests
promises-aplus-tests myPromise.js
如果单元测试通过,证明我们的Promise符合Promise A+规范
完整代码
const STATUS = {
"PENDING": "pending",
"FULFILLED": "fulfilled",
"REJECTED": "rejected"
}
//解析x类型,决定promise2走成功还是失败
function resolvePromise(promise2, x, resolve, reject) {
if (x == promise2) {
return reject(new TypeError("返回值错误,不能使用同一个promise"))
}
//只有object或者function才能是Promise
if ((typeof x === 'object' && x !== null) || typeof x === 'function') {
let called = false;//成功或者失败方法只能调用一次,防止其他Promise实现错误
try {
let then = x.then;//通过判断x上是否有then函数,判断x是否是一个Promise
if (typeof then === 'function') {
then.call(x, y => {
if (called) return;
called = true;
// resolve(y) y有可能还是promise 递归解析 直到是普通值为止
resolvePromise(promise2, y, resolve, reject);
}, r => {
if (called) return;
called = true;
reject(r);
})
} else {
resolve(x);
}
} catch (error) {
if (called) return;
called = true;
reject(error);
}
} else {
resolve(x);
}
}
class Promise {
/**
* Creates a new Promise.
*
* @param executor — A callback used to initialize the promise.
* This callback is passed two arguments: a resolve callback used to resolve the promise
* with a value or the result of another promise, and a reject callback used to reject the
* promise with a provided reason or error.
*/
constructor(executor) {
this.status = STATUS.PENDING;
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.status === STATUS.PENDING) {
this.status = STATUS.FULFILLED;
this.value = value;
this.onResolvedCallbacks.forEach(fn => fn());
}
};
const reject = (reason) => {
if (this.status === STATUS.PENDING) {
this.status = STATUS.REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error)
}
}
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled — The callback to execute when the Promise is resolved.
* @param onrejected — The callback to execute when the Promise is rejected.
* @returns — A Promise for the completion of which ever callback is executed.
*/
then(onfulfilled, onrejected) {
//判断then传递的参数是否是函数,如果不是则包装成一个函数
onfulfilled = typeof onfulfilled === 'function' ? onfulfilled : x => x;
onrejected = typeof onrejected === 'function' ? onrejected : error => {
throw error
};
let promise2 = new Promise((resolve, reject) => {
if (this.status === STATUS.FULFILLED) {
setTimeout(() => { //创建一个宏任务,保证promise2已完成创建
try {
let x = onfulfilled(this.value); //x的返回值有可能是一个新的Promise,需要进行判断和处理
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error) //如果返回异常,捕获并作为失败结果返回
}
// resolve(x)
}, 0);
}
if (this.status === STATUS.REJECTED) {
setTimeout(() => {
try {
let x = onrejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error)
}
// reject(x)
}, 0);
}
if (this.status === STATUS.PENDING) {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onfulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error)
}
}, 0)
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onrejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error)
}
}, 0);
});
}
});
return promise2;
}
catch(errFn) {
return this.then(null, errFn);
}
}
Promise.deferred = function () {
let dfd = {};
dfd.promise = new Promise((resolve, reject) => {
dfd.resolve = resolve;
dfd.reject = reject;
})
return dfd;
}
module.exports = Promise;