Promise与自定义封装Promise

1,034 阅读5分钟

1. 声明一个Promise

function Promise(executor) {
	// 执行器函数在里面时同步调用的
	// 添加属性
	this.PromiseState = 'pending'
	this.PromiseResult = null
	this.callback={};
	// 保存实例对象this的值
	const self = this
	// 声明resolve,reject
	function resolve(data) {
		// 判断状态是不是修改过
		if (self.PromiseState !== 'pending') return;
		console.log(this) //这里的this指的时全局对象,并不是实例对象
		// 1.修改对象的状态(promiseState)
		self.PromiseState = 'fulfilled'
		// 2设置对象的结果值(PromiseResult)
		self.PromiseResult = data
		// 调到成功的回调
		if(self.callback.onResove){
		   self.callback.onResove(data)
		})
	}

	function reject(data) {
		console.log(this) //这里的this指的时全局对象,并不是实例对象
		// 判断状态是不是修改过
		if (self.PromiseState !== 'pending') return;
		// 1.修改对象的状态(promiseState)
		self.PromiseState = 'rejected'
		// 2设置对象的结果值(PromiseResult)
		self.PromiseResult = data
		// 调到成功的回调
		if(self.callback.onReject){
			self.callback.onReject(data)
		})
	}
	try {
		// 调用
		executor(resolve, reject);
	} catch (e) {
		// 修改promise对象的状态为失败
		reject(e);

	}



}
// 声明的没有then方法,为了能顺利调用,添加then方法,调用了两个形参,所以得声明两个实参
Promise.prototype.then = function(onResove, onReject) {
	// 调用回调函数
	if (this.PromiseState === 'fulfilled') {
		onResove(this.PromiseResult);

	}
	if (this.PromiseState === 'rejected') {
		onReject(this.PromiseResult);
	}
	// 判断pending状态
	if(this.PromiseState==='pending'){
		// 保存回调函数
		this.callback={
			onResove:onResove,
			onReject:onReject,
		}
	}
}
let p =new Promise((resolve,reject)=>{
		// resolve('success')
		// 改变状态 reject  resolve 抛出异常 throw 'err'
		// throw 'err'
		// 抛出的就是失败的值
		setTimeout(() {
			resolve('success')
		}, 1000);
		// 异步的时候改变状态的时候,才会执行回调
});
p.then(value=>{
	console.log(value)
},reason=>{
	console.log(reason)
})

2.状态

进行中,成功,失败,状态的转化只有两种

pending变成resolved

pending变成rejected

状态只能改一次,不论成功还是失败,都会有一个数据结果

3.对象的值

promise结果保存着异步任务失败或者成功的结果

resolve

reject

4.基本流程

创建promise实例对象,执行异步操作,then返回一个新的Promise对象

5.catch的回调,捕获错误

6.promise.resolve() 传入的状态永远都是成功的

当一个函数被期望返回一个 promise 时,这个方法用于兼容性。(译注:这里的兼容性是指,我们直接从缓存中获取了当前操作的结果 value,但是期望返回的是一个 promise,所以可以使用 Promise.resolve(value) 将 value “封装”进 promise,以满足期望返回一个 promise 的这个需求。)

7.promise.resolve() 传入的状态永远都是失败的 用法与promise.resolve()一样

8.Promise.all();

Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例

(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

9.Promise.race();

Promise.race()方法是将多个Promise实例包装为一个实例;

const p = Promise.race([p1, p2, p3]);

上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

Promise.race方法的参数与Promise.all方法一样,如果不是 Promise 实例,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理

10.如果修改Promise对象的状态

1)调用resolve函数

2)调用reject函数

3)抛出错误

let p=new Promise((resolve,reject)=>{
	//1.resole 函数
	resolve('ok');//pending => fulfilled(resolved)
	//2.reject 函数
	reject('err');//reject => rejected
	// 3.抛出错误
	throw '有错误啦'
})

11.只要Promise状态改变对应的回调都会执行

let p=new Promise((resolve,reject)=>{
	//1.resole 函数
	resolve('ok');//pending => fulfilled(resolved)

})
p.then(value=>{
	alert(value)
})

p.then(value=>{
	alert(value)
})

12.then的返回结果

let p=new Promise((resolve,reject)=>{
	//1.resole 函数
	resolve('ok');//pending => fulfilled(resolved)

})
p.then(value=>{
	alert(value)
	// 1抛出错误 新的promise变成rejected为抛出的异常
	throw '出了问题'
	// 2返回的结果是非promise类型的对象 新的promise变成resolved value为返回值
	return 521
	// 3返回的结果是promise对象 promise的结果就会变成新promise的结果
	return new Promise((resolve,reject)=>{
		resolve('success')
	})
})

p.then(value=>{
	alert(value)
})

13.Promise的异常穿透

// 当使用promise的then链式调用时,可以在最后指定失败的回调
// 前面任何操作出了异常,都会/可以传到最后失败的回调中处理
let p =new Promise((resolve,reject)=>{
	setTimeout(()=>{
		reject('err')
	},1000)
});
p.then(value=>{
	console.log(1111)
}).then(value=>{
	console.log(2222)
}).catch(reason=>{
	console.log(reason)
})

14.中断promise链条

let p =new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve('success')
	},1000)
});
p.then(value=>{
	console.log(1111)
	// 中断promise链条,返回一个pending状态的promise对象,
	// 只有在状态改变的时候下边才会只能,但是返回的是一个pending状态的promise,所以then的返回结果也是pending状态的promise
	return new Promise(()=>{})
}).then(value=>{
	console.log(2222)
}).catch(reason=>{
	console.log(reason)
})

15.await与async

async  function main(){
	1.如果返回值是一个非promise类型的数据,返回的时成功的promise
	2.返回的是promise,由promise的状态决定
	3.抛出异常 返回结果就是一个失败的promise
}
let  result =main()

console.log(result)

// async返回结果也是一个promise对象

await 右侧表达式一般是promise对象,但也可以是其他形式

1.如果是是promise对象,await返回的是promise成功的值

2.如果表达式是其他值,直接将此值作为await的返回值

await必须写在async中,但是async可以没有await

await的promise失败了,需要通过try...catch()捕获处理

//async与 await结合使用
// 如果出错,直接用try..catch()
const fs=require('fs')
const until=require('util')
const mineReadFile=util.promisify(fs.readFile)
async function main(){
	let data1=await mineReadFile('1.html')
	let data2=await mineReadFile('2.html')
	let data3=await mineReadFile('3.html')
}
main()
// 结合发送ajax请求
let btn=document.querySelector('btn')
btn.addEventListener('click',async function(){
	let duanzi=await sendAjax('url接口')
})