JavaScript异步 ES6 Promise对象

简介

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的方法。
在这里插入图片描述
上面这段代码输出:在这里插入图片描述
我在promise中写的是if(true)那么会执行resolve(),然后.then就会执行第一个参数的方法,也就是输出“成功了”。

创建成功或失败的Promise对象

就是说如果你只需要处理成功结果或者只需要处理失败结果,那就可以简写。下边的写法都是等价的。
在这里插入图片描述
可以用then的第二个参数方法捕获错误,也可以用catch捕获错误。写法都是等价的。
在这里插入图片描述
补充

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()处理。
在这里插入图片描述
当然了, promise的参数可以用正常的函数,写箭头函数也可以

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

举个栗子

例子中可以看到我的请求成功了。if语句进入了resolve(pro),然后将参数传给then,then就执行了resolve,输出了我请求到的结果。
在这里插入图片描述

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"}
			})
		})
发布了131 篇原创文章 · 获赞 451 · 访问量 54万+

猜你喜欢

转载自blog.csdn.net/qq_36667170/article/details/105053979