Promise基础入门

203 阅读3分钟

Promise是异步编程的一种解决方案,它有三种状态,分别是

pending-进行中
resolved-已完成
rejected-已失败

当Promise的状态由pending 转变为resolved或rejected时,会执行相应的方法,并且状态一旦改变,就无法再次改变状态,这也是它名字promise承诺的由来。

Promise的作用

一个Promise对象可以理解为一次将要执行的操作(常常被用于异步操作),使用了Promise对象之后可以用一种链式调用的方式来组织代码,让代码更加直观。

Promise对象有以下两个特点。

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

then

function printHello (ready) {
	return new Promise(function (resolve, reject) {
		if (ready) {
			resolve("Hello");
		} else {
			reject("Good bye!");
		}
	});
}

function printWorld () {
	alert("World");
}

function printExclamation () {
	alert("!");
}

printHello(true)
	.then(function(message){
		alert(message);
	})
	.then(printWorld)
	.then(printExclamation);

上述例子通过链式调用的方式,按顺序打印出了相应的内容。then可以使用链式调用的写法原因在于,每一次执行该方法总是会返回一个Promise对象。另外,在then onFulfilled的函数当中的返回值,可以作为后续操作的参数,因此上面的例子也可以写成

 printHello(true).then(function (message) {
	return message;
}).then(function (message) {
	return message  + ' World';
}).then(function (message) {
	return message + '!';
}).then(function (message) {
	alert(message);
});

catch

.catch()的作用是捕获Promise的错误,与then()的rejected回调作用几乎一致。但是由于Promise的抛错具有冒泡性质,能够不断传递,这样就能够在下一个catch()中统一处理这些错误。同时catch()也能够捕获then()中抛出的错误,所以建议不要使用then()的rejected回调,而是统一使用catch()来处理错误

Promise.all

Promise.all可以接收一个元素为Promise对象的数组作为参数,当这个数组里面所有的Promise对象都变味resolve时,该方法才会返回。

function p1(ready){
		return new Promise(function(resolve,reject){
			if(ready){
				setTimeout(function () {
					resolve("Hello");
				}, 3000);
			}
		})
	}
	function p2(ready){
		return new Promise(function(resolve,reject){
			if(ready){
				setTimeout(function () {
					resolve("World");
				}, 1000);
			}
		})
	}  


Promise.all([p1(true), p2(true)]).then(function (result) {
	console.log(result); // ["Hello", "World"]
});

上面的例子模拟了传输两个需要数据不同的市场,虽然p2的速度比p1要快,但是Promise.all方法会按照数组里面的顺序将结果返回 日常开发中经常会遇到这样的需求,在不同的接口请求数据然后拼合成自己所需的数据,通常这些接口之间没有关联 例如不需要前一个接口的数据作为后一个接口的参数,这个时候Promise.all方法就可以派上用场了。

Promise.race

同样接受一个数组,武罗这个数组的状态是rosolve合适reject,该方法都会返回 返回的值取决于第一个promise为resolve的值,如果都为resolve,只返回第一个resolve的值

Promise.race([p1(false), p2(true)]).then(function (result) {
	console.log(result); // ["Hello", "World"]
});