promise

174 阅读3分钟

一、promise的概念:

Promise是一个构造函数,也是一个对象,promise用于保存异步执行的结果。构造函数接受1一个执行函数作为参数,执行函数接受2个参数resovel、reject作为执行完成的回调函数。通过then方法处理回调的结果,then方法的返回值也是一个promise对象,所以promise支持链式调用。

var p=new Promise(function(resovel,reject){})

image.png

promise的三种状态:

1、 待定(pending) : 初始状态,既没有被兑现,也没有被拒绝;

2、已完成(fulfilled):操作成功完成;

3、已失败(reject):操作失败完成。

这也意味着,不管是成功或者失败,保存到执行后的结果,而且它的状态是不可逆的,不管取值多少次都是不会改变的。代码如下:

var p = new Promise(function(resovel, reject) {
	var score = Math.random() * 100
	if (score > 98) {
		throw new Error('系统错误')
	} else if (score < 60) {
		reject('考试失败')
                throw new Error('reject')
	} else {
		resovel('考试成功')
                throw new Error('resovel')
	}
})
 p.then(resove => {
	console.log('第一次打印结果::', resove);
	return 'good'
}, reject => {
	console.log('第一次打印结果::', reject);
	return 'bad'
}).then(resove => {
	console.log('p2::', resove);
}, reject => {
	console.log('p2::', reject);
})
			

特点1、 即使执行函数内部抛出异常也会触发reject

特点2、 只要执行resovle、reject,也就是状态固化之后,后面的代码抛出的异常捕获不到。

var p = new Promise(function(resovel, reject) {
	var score = Math.random() * 100
	// 执行reject
	// throw Error('前面抛出异常')
	if (score > 60) {
		resovel('考试成功')
	} else {
		reject('考试失败')
	}
	//忽略这个异常
	// throw Error('后面抛出异常')
})
			
p.then(resove => {
	console.log(resove);
}, reject => {
	console.log( reject);
}).catch((err)=>{
	console.log(err);
})

特点3、 异常存在冒泡,可以在.then()的后面捕获到异常

var p = new Promise(function(resovel, reject) {
	console.log(123);
	throw Error('后面抛出异常')
})
			
p.then(resove => {
	console.log(resove);
}, reject => {
	console.log( reject);
}).then().catch((err)=>{
	console.log(err);

特点4、 如果执行函数内部调用了reject,必须提供reject的处理函数或者提供捕获异常的处理,否则会报promise.html:1 Uncaught (in promise):现象代码:

var p1 = new Promise((resovle, reject) => {
	reject('reject')
})
p1.then(resove => {
	console.log(resove);
})		

解决代码:如果reject和catch都提供,rejecte的优先级高。

var p1 = new Promise((resovle, reject) => {
	reject('reject')
})
p1.then(resove => {
},reject=>{
	console.log(reject);
}).catch((err) => {
	console.log(err+22);

特点5、状态依赖:

p2的状态依赖于p1的状态

var p1 = new Promise((resovle, reject) => {
	setTimeout(function() {
		resovle('error')
	}, 4000)
})
var p2 = new Promise((resovle, reject) => {
	setTimeout(function() {
		resovle(p1)
	})
})
p2.then(function(res) {
	console.log('p2', res);
})
p1.then(function(res) {
	console.log('p1', res);
})

二、promise的状态管理

2-1、all 所有的都成功,或者一旦有一个失败就返回;

参数:iterable类型参数;

返回值:成功返回数组,按照参数输入顺序返回,失败返回第一个失败的结果。

var p1 = new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve('p1')
		}, Math.random() * 1000)
	}),
	p2 = new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve('p2')
			// reject('p2')
		}, Math.random() * 1000)
	}),
	p3 = new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve('p3')
		}, Math.random() * 1000)
	}),
	arr = [p1, p2, p3],
	set = new Set([p1, p2, p3]),
	// pall = Promise.all(arr);
	pall = Promise.all(set);
pall.then(res => {
	console.log(res)// ["p1", "p2", "p3"]
}, err => {
	console.log(err)//p2
})

2-2、any 所有的都失败或者有一个成功就返回;

参数:可迭代对象Iterable;

返回值:第一个成功的结果或者AggregateError: All promises were rejected

var p1 = new Promise((resolve, reject) => {
		setTimeout(() => {
			reject('p1')
		}, Math.random() * 1000)
	}),
	p2 = new Promise((resolve, reject) => {
		setTimeout(() => {
			// reject('p2')
			resolve('p2')
		}, Math.random() * 1000)
	}),
	p3 = new Promise((resolve, reject) => {
		setTimeout(() => {
			reject('p3')
		}, Math.random() * 1000)
	}),
	arr = [p1, p2, p3],
	pall = Promise.any(arr);
pall.then(res => {
	console.log(res)//p2
}, err => {
	console.log(err)//AggregateError: All promises were rejected
})

2-3、race 如果有一个有执行结果就返回,不管成功或者失败

参数:可迭代对象Itarable

返回值:执行结果

var p1 = new Promise((resolve, reject) => {
		setTimeout(reject, Math.random() * 1000,'p1')
	}),
	p2 = new Promise((resolve, reject) => {
		setTimeout(resolve, Math.random() * 1000,'p2')
	}),
	p3 = new Promise((resolve, reject) => {
		setTimeout(reject, Math.random() * 1000,'p1')
	}),
	arr = [p1, p2, p3,],
	pall = Promise.race(arr);
pall.then(res => {
	console.log('res::',res)//res::p2
}, err => {
	console.log('err::',err)//err::p1、err::p3
})