欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ES6 Promise对象

程序员文章站 2022-07-13 09:12:23
...

简介

Promise对象: 代表了未来某个将要发生的事件(通常是一个异步操作)。
简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
ES6中的promise对象, 可以将异步操作以同步的流程表达出来,很好地解决了回调地狱的问题。

回调地狱:回调函数层层嵌套或者其他回调函数高耦合的现象。回调地狱如果有一个出错会影响到很多其他的部分,并且很难进行维护和二次开发。

promise对象的3个状态

  • 初始化状态(等待状态):pending
  • 成功状态:fullfilled
  • 失败状态:rejected

使用promise的基本步骤

  1. 创建promise对象
  2. 调用promise的回调函数then()

Promise对象有以下两个特点。

  1. 对象的状态不受外界影响。 三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
  2. 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。

语法

创建一个promise对象语法如下:

const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});
  • Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
  • resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
  • reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

.then

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

举个栗子

下面这个代码可以看出promise构造函数的参数是一个箭头函数,箭头函数有两个参数resolve, reject。进入这个箭头函数时候状态为“pending”
if语句判断异步操作的执行状况:

  • 如果成功就执行resolve(),promise的状态会被自动修改为fullfilled。
  • 如果失败就执行reject(),promise的状态会被自动修改为rejected。

if语句的结果,也就是执行了resolve()还是reject(),不论哪一个,都可以给promise.then()传递参数。promise.then(function(value) { // success}, function(error) { // failure }); 如果成功,promise.then就会执行参数1的方法,如果失败,就会执行参数2的方法。
ES6 Promise对象
上面这段代码输出:ES6 Promise对象
我在promise中写的是if(true)那么会执行resolve(),然后.then就会执行第一个参数的方法,也就是输出“成功了”。

创建成功或失败的Promise对象

就是说如果你只需要处理成功结果或者只需要处理失败结果,那就可以简写。下边的写法都是等价的。
ES6 Promise对象
可以用then的第二个参数方法捕获错误,也可以用catch捕获错误。写法都是等价的。
ES6 Promise对象
补充

promise
.then(result => {···})		//两个参数方法,前面正确后面错误
.catch(error => {···})		//一个参数方法,只处理错误
.finally(() => {···});		//一个参数方法,正确错误都可以处理,ES2018出现

promise和AJAX

正常我们写ajax是这样:

			var pro = new XMLHttpRequest;
			pro.open(method, url);
			pro.onreadystatechange = function() {
				if (pro.readyState == 4) {
					if (pro.status == 200 || pro.status == 304) {
						//处理成功请求
					} else {
						//处理失败请求
					}
				}
			}
			pro.send();

那promise怎么和ajax结合呢。只要把这段代码搬到promise的参数方法中即可。然后就可以将if语句用resolve()和reject()处理。
ES6 Promise对象
当然了, promise的参数可以用正常的函数,写箭头函数也可以

		var ajaxPro = new Promise((resolve, reject) => {})
		var ajaxPro = new Promise(function(resolve, reject) {})

举个栗子

例子中可以看到我的请求成功了。if语句进入了resolve(pro),然后将参数传给then,then就执行了resolve,输出了我请求到的结果。
ES6 Promise对象

ajax的原生方法fetch

下边的代码就是我把上边截图的可以改进一下,把promise封装了起来了,然后把返回的内容用JSON.parse()转为了JavaScript的字符串。

		let myUrl = "ajax/13promise.json";

//封装起来
		function promise(url) {
			return new Promise(function(resolve, reject) {
				var pro = new XMLHttpRequest;
				pro.open("GET", url);
				pro.onreadystatechange = function() {
					if (pro.readyState == 4) {
						if (pro.status == 200 || pro.status == 304) {
							resolve(pro);
						} else {
							reject(pro);
						}
					}
				}
				pro.send(null);
			})
		}
//调用
		var ajaxPro = promise(myUrl);
		
		ajaxPro.then(function(result) {
			var res = JSON.parse(result.responseText);
			console.log(res);		//输出 {name: "promisezzz", demo: "hahahahdemo"}
		}, function(err) {});

上边这段代码只是帮助理解promise而已,实际写的时候用ajax的fetch方法就好。下面给出fetch方法:

		let myUrl = "ajax/13promise.json";
		fetch(myUrl).then(function(result){
			var res = result.json();
			res.then(function(response){
				console.log(response);		//输出 {name: "promisezzz", demo: "hahahahdemo"}
			})
		})