Promise use and basic source code implementation (1)

1. Use

<!DOCTYPE html>
<html lang="zh-cn">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title></title>
		<style>
			
		</style>
		<script src="./customePromise.js"></script>
<script>
	// new Promise返回的对象称之为Promise对象
	/*
		三种状态:
			pending 正在进行
			fulfilled 已完成
			rejected 已失败

		1. new Promise 接收一个函数 executor
		2. 函数 executor 接收两个参数,resolve,reject
			调用resolve的时候,把promise对象转成成功状态
			调用reject的时候,把promise对象转成失败状态
		3. promise对象的then方法来注册成功状态或者失败状态要执行的函数
			p.then(resolveFunc,rejectFunc);
			p.then(resolveFunc,rejectFunc);
			p.then(resolveFunc,rejectFunc);
			p.then(resolveFunc,rejectFunc);

			实现是一个promise对象调用多次then方法

		5. then函数的链式操作
			p.then().then().then();

			就是then函数执行后返回一个promise对象

		6. thenable
			拥有 then 方法的对象或函数
			{
				then(){}
			}

			promise对象也拥有then方法

		7. 当给resolve传入一个promise对象的时候,只有等到promise对象装成成功或者失败,resolve才会成功

		8.resovle要接受的参数
			1. 简单值
			2. 接收thenable对象

		9.then中成功或失败执行的函数的返回值
			1. 有简单类型返回值,作为then方法返回的promise对象的成功状态的值
		
			2. 当返回一个thenable对象的时候,只有是成功状态才能执行下一个then

	*/

	let p2 = new CustomePromise((resolve,reject) => {
		setTimeout(() => {
			resolve('p2,成功');	
		},5000)
	});

	p2.then((data) => {
		console.log('p2then',data)
	})

	let p = new CustomePromise((resolve,reject) => {
		setTimeout(function (){
			resolve(p2);	
		},1000)	
	});

	p.then((data) => {
		console.log('第一个then成功',data)
	},(error) => {
		console.log('第一个then失败',error)
	});

	p.then((data) => {
		console.log('第一个then成功',data)
	},(error) => {
		console.log('第一个then失败',error)
	});

	console.log('我先执行')

	document.onclick = function (){
		console.log(p)
		p.then((data) => {
			console.log(data)
		})	
	}

	// Promsie中直接调用了resolve,是then下面的代码先执行还是,then的成功注册的函数先执行

	/*
	// 思考题:
		let p = new Promise((resolve) => {
			console.log(1)
			resolve()
		})

		p.then(() => {
			console.log(2)
		})

		console.log(3)

	*/



</script>
	</head>

	<body>
		
	</body>
</html>

Second, the basic source code implementation

;(function(){

	const status = {
		pending: 0,
		fulfilled: 1,
		rejected: 2
	}

	class CustomePromise{
		constructor(func){
			// 初始状态
			this._status = status.pending;
			this._value = null;  // 记录resolve函数传入的参数
			this._error = null;  // 记录reject函数传入的参数

			// 收集成功状态要执行的函数
			this.resolvedArr = [];
			// 收集失败状态要执行的函数
			this.rejectedArr = [];

			this._handler(func)
		}
		// 判断value有没有then函数,并且拿出then函数
		_getThen(value){
			let type = typeof value;
			if(value && (type === 'object' || type === 'function')){
				let then;
				if(then = value.then){
					return then;
				}
			}

			return null;
		}
		// 接收外部传入的函数,调用外部传入的函数
		_handler(func){
			let done = false; // 就是让函数值执行一次
			func((value) => {
				if(done) return;
				done = true;

				// value有没有then函数
				let then = this._getThen(value);
				if(then){
					// 拿到对象的then之后,怎么知道这个promise对象完成了呢?
					// 在then函数上注册成功和失败函数就可以
					return this._handler(then.bind(value))
				}

				this._resolve(value);
			},(error) => {
				if(done) return;
				done = true;
				// value有没有then函数
				let then = this._getThen(error);
				if(then){
					// 拿到对象的then之后,怎么知道这个promise对象完成了呢?
					// 在then函数上注册成功和失败函数就可以
					return this._handler(then.bind(error))
				}
				this._reject(error);
			});
		}

		_resolve(value){
			
			setTimeout(() => {
				// 把状态改为成功
				this._status = status.fulfilled;
				this._value = value;
				// 执行所有成功的函数
				this.resolvedArr.forEach(item => {
					item(this._value)
				})
			})
		}
		_reject(error){
			setTimeout(() => {
				// 把状态改为失败
				this._status = status.rejected;
				this._error = error;

				this.rejectedArr.forEach(item => item(this._error));
			})
		}
		// 收集注册的成功状态或失败状态要执行的函数
		_done(resolvedFunc,rejectedFunc){
			//pending的时候收集
			resolvedFunc = typeof resolvedFunc === 'function' 
							? resolvedFunc : null;
			rejectedFunc = typeof rejectedFunc === 'function' 
							? rejectedFunc : null;

			// 收集
			if(this._status === 0){
				if(resolvedFunc) this.resolvedArr.push(resolvedFunc);
				if(rejectedFunc) this.rejectedArr.push(rejectedFunc);
			}else if(this._status === 1 && resolvedFunc){ // 直接执行
				resolvedFunc(this._value);
			}else if(this._status === 2 && rejectedFunc){
				rejectedFunc(this._error);
			}
		}

		// 收集注册的成功状态或失败状态要执行的函数
		// 返回一个promise对象
		then(resolvedFunc,rejectedFunc){
			//this._done(resolvedFunc,rejectedFunc)
			return new CustomePromise((resolve,reject) => {
				this._done(
					(value) => {
						// resolvedFunc不是一个函数
						if(typeof resolvedFunc !== 'function'){
							return resolve(value);
						}
						resolve(resolvedFunc(value));
					},
					(error) => {
						if(typeof rejectedFunc !== 'function'){
							return reject(error);
						}
						reject(rejectedFunc(error))
					}
				)
			})
		}
	}

	window.CustomePromise = CustomePromise;

})();

 

Published 35 original articles · won praise 1 · views 6718

Guess you like

Origin blog.csdn.net/qq_36162529/article/details/104187476