基于promiseAPlus 实现 Promise

promise的目的:实现异步调用和解决回调多层嵌套的问题

一、promise是什么:promise是一个构造函数,但是不能被直接调用,只能通过new 执行,否则报 “TypeError: Promise constructor cannot be invoked without 'new'”.比如:proimse()就会报错。

构造数接收一个函数作为参数,返回一个promise对象:简单用法:

function executor(resovle,reject){
	resovle(1)
}
let p= Promise(executor);
 p.then(res=>{
 	console.log(res);
 },err=>{
 	console.log(err);
 })

Promise的3种状态:

1、pending ;

2、fulfilled

3、rejected

promise的特点:通过现象看本质

现象一:

function executor1(resovle, reject) {
	resovle("成功")
	reject("失败")
	throw "error"
}
function executor2(resovle, reject) {
	reject("失败")
	resovle("成功")
	throw "error"
}
function executor3(resovle, reject) {
	throw "error"
	reject("失败")
	resovle("成功")
}
let p1 = new Promise(executor1);
let p2 = new Promise(executor2);
let p3 = new Promise(executor3);
console.log(p1);
console.log(p2);
console.log(p3);

结论:

1、状态一旦被改变就不可逆,执行的结果也是不可变的,状态只能从: pending->fulfilled 或者 pending->rejected 。

2、执行器函数内部抛出的异常:状态也是rejected,在promise里面的构造函数调用executor函数时,通过try...catch(e) 捕获了异常,在catch块里面执行了reject(e)方法。

现象二then方法的调用和链式调用:

 结果:

 

 结论:

3、then 方法的参数只有函数才有效: then 方法接收2个可传参数,如果参数不传或者不是函数就会被忽略掉,请看30和31行代码。

4、then方法的回调函数的返回值做为下一次then的结果。

注:函数如果不写return,等价return undefined。

5、返回值可以向下传递:第三个then可以打印出第二个then的返回值。

6、then方法的返回值为非promise 对象。

问题1、37行的返回值是一个promise对象,为什么下一次then的回调不是promise对象?

7、执行器里面执行resolve回调then的一个函数,执行reject回调第二函数。

8、回调函数里面抛异常,执行下个then的第二个回调函数。 34行和36  

现象三:catch方法

 结论:

9、catch方法,等价于then(null,err=>{})

promise a plus文档:   https://promisesaplus.com/

Promise的大概实现如下,只是实现了大概的思想,并没有完全遵守Promise A+的规范:

const PENDING = 'pending';
const Fulfilled = 'fulFilled';
const REJECTED = 'rejected';
export default class MyPromise {
	constructor(executor) {
		this.status = PENDING;
		this.reason = undefined;
		this.value = undefined;
		this.fulFilledCallback = () => {};
		this.rejectedCallback =  () => {};
		try {
			executor(this.resolve, this.reject);
		} catch (e) {
			this.reject(e)
		}
	}
	resolve = (res) => {
		if (this.status === PENDING) {
			this.status = Fulfilled;
			this.value = res;
			this.fulFilledCallback()
		}
	}
	reject = (reason) => {
		if (this.status === PENDING) {
			this.status = REJECTED;
			this.reason = reason;
			this.rejectedCallback();
		}
	}
	static resolve(res) {
		return new myPromise((resovle, reject) => {
			resovle(res)
		})
	}
	static reject(res) {
		return new myPromise((resovle, reject) => {
			reject(res)
		})
	}
	catch (res) {
		return this.then(null, res)
	}
	then(onFulFilled, onRejected) {
		onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : data => data;
		onRejected = typeof onRejected === 'function' ? onRejected : err => {
			throw err
		};
		let promise2 = new myPromise((resovle, reject) => {
			if (this.status === Fulfilled) {
				setTimeout(() => {
					let x = onFulFilled(this.value)
					resolvePromise(promise2, x)
				})
			}
			if (this.status === REJECTED) {			
				setTimeout(() => {
					try {
						let x = onRejected(this.reason)
						resolvePromise(promise2, x)
					} catch (e) {
						reject(e)
					}
				})
			}
			if (this.status === PENDING) {
				this.fulFilledCallback = () => {
					let x = onFulFilled(this.value)
					resolvePromise(promise2, x)
				}
				this.rejectedCallback = () => {
					let x = onRejected(this.reason)
					resolvePromise(promise2, x)
				}
			}
		})
		return promise2;
	}
}


function resolvePromise(promise2, x) {

	if (x instanceof myPromise) {
		let then = x.then;
		then.call(x, value => {
			setTimeout(() => {
				let v = getValueK(value);
				resolvePromise(promise2, v)
			})
		}, err => {
			promise2.reject(err)
		})
	} else {
		promise2.resolve(x)
	}
}

function getValueK(promise) {
	if (promise instanceof myPromise) {
		getValueK(promise.value)
	} else {
		return promise
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值