彻底搞懂ES6中的Promise

2 篇文章 0 订阅
1 篇文章 0 订阅

在搞懂Promise之前,首先得先知道为什么会出现Promise

Promise出现的缘由?

在Promise出来之前,要想在一个网络请求结果到达之后再去执行其他的请求,也就是一个请求依赖于上一个请求结果,那么就可能造成不断嵌套的情况,如下:

$.ajax({
	url: 'xxx',
	success: function () {
		$.ajax({
			url: 'yyy',
			success:function () {
				$.ajax({
					url: 'zzz',
					success: function () {
						...
					}
				})
			}
		})
	}
})

这样就形成了循环嵌套,一层套一层,形成了 回调地狱,这样就导致代码的臃肿,可读性差,耦合度高,可服用性差,这时就到Promise闪亮登场了

Promise含义

Promise是异步编程的一种解决方案,比传统的解决方案——回调和事件监听更合理和强大。
Promise就像一个容器,保存着未来才会执行事件的结果.Promise就是一个对象,可以获取异步操作的消息。

Promise特点:

  1. Promise对象状态不受外界的影响。Promise有三种状态:pending进行中、resolve已成功、reject已失败。只有异步操作的结果可以决定Promise对象处于哪种状态,其他任何操作都不能改变对象的状态
  2. Promise对象状态一旦改变就不能再变,这只有两种情况:pending到resolve或者pending到reject的转变,一旦状态改变了,状态相当于凝固了,给promise对象添加任何回调,得到的还是那种结果

Promise相关Api

1.Promise对象自身上的api

Promise.resove
Promise.resolve(val) 是将val转换成promise对象,最后的结果还要根据它的参数而决定:
1、val是thenable(有then方法)的对象,那么Promise.resove会追踪这个对象的then方法,也就是将val这个对象转换为Promise对象,然后执行thenable的then方法
2、val是个Promise对象,那么Promise.resolve会把这个Promise原封不动的返回
3、val不具有then方法或者根本不是对象,那么Promise.resolve会返回一个状态为resolve的Promise对象,它的resove的回调函数参数就是这个val

Promise.reject
Promise.reject返回一个状态为reject的Promise对象,跟Promise.resolve不同的是,Promise.resolve会把接收的参数原封不动的当做reject的理由,变成后续回调的参数

Promise.all([a, b, c])
Promise.all接收一个数组或者具有iterator的对象,会将多个Promise转化成一个Promise,如果传入的不是Promise对象,那么会通过调用Promise.resolve将它转化成对象。只有a,b,c三个对象的状态都变成了resolve状态,那么最后得到的promise对象才是resolve状态,a,b,c的返回值组成数组传递给回调函数;一旦a,b,c中有一个变成了reject状态,那么得到的Promise对象就是reject状态,并将那个reject的返回值传递给回调函数

2.Promise实例对象的api

Promise.prototype.then
Promise.prototype.then是Promise对象状态改变的回调函数,接收两个参数,分别是resolve状态的回调和reject状态的回调,then方法里返回一个新的Promise对象不是原来的对象,因此可以链式调用,可以在then里返回一个Promise对象(有异步操作),这时后一个回调就要等这个Promise状态改变才被调用

Promise.prototype.catch
Promise.prototype.catch是.then(null, rejection)和.then(undefined, rejection)的别名,如果前面的Promise链中有Promise状态变为reject,就会调用catch的回调,或者then回调执行过程中发生错误,也会执行catch的相关回调,也就是用于捕捉错误

Promise.prototype.finally
Promise.prototype.finally不论Promise状态为哪种,都会执行finally的操作,因此finally的回调里没有参数,因为不用依赖于Promise的状态都会执行的操作。实际中可以在finally中设置loading的为false,不论Promise的异步操作是成功还是失败,加载的字段loading都应该是完成的状态

Promise的问题

  1. promise一旦创建立即执行,不能中途取消
  2. 如果不设置回调,Promise内部的错误无法在外部捕获
  3. 当状态为pending时,无法得知目前进展到哪一阶段

基础使用

1.异步加载图片
function loadPic(url) {
	return new Promise((resolve, reject) {
		let image = new Image();
		image.onload = function () {
			resolve(image)
		}
		image.onerror = function () {
			reject(new Error('Not get image at '+ url))
		}
		image.src = url;
	})
}
2. 使用promise封装ajax操作
function ajax(url, method, data) {
	return new Promise((resolve, reject) {
		let xhr = null;
		if (window.XMLHttpRequest) {
			xhr = new XMLHttpRequest();
		} else {
			xhr = new ActiveXObject('Microsoft.XMLHTTP')
		}
		
		if (method === 'GET') {
		 	xhr.open(method, url+"?"+data, true)
		} else {
			xhr.open(method, url, true)
		}
	})
	xhr.onreadstatechange = function () {
		if (this.readystate !== 4) {
			return;
		}
		if (this.status === 200) {
			resolve(this.responseText)
		} else {
			reject(new Error(this.statusText))
		}
	}
	if (method === 'GET') {
		xhr.send();
	} else {
		xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
		xhr.send(data)
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值