es6基础 --- 9、异步编程 promise

异步编程

js中的单线程是指负责执行代码的线程只有一个,这样设计的初衷是js是用来操作DOM的,多线程会产生DOM操作冲突。

缺点:执行耗时任务时会阻塞代码执行,出现假死状态。

解决:有同步模式和异步模式。JS代码执行是单线程,但是浏览器是多线程的,因此可以借用浏览器的多线程去执行一些耗时任务,如ajax请求。是同步模式还是异步模式是由运行环境提供的API来决定的。

取个例子:一段代码中用promise封装了一个ajax请求,利用浏览器的多线程去请求这个ajax请求,该段代码继续执行,请求完成后,promise.then中的回调函数会添加到代码段的最后去执行。这样,解决了耗时任务阻塞代码执行的问题。

回调函数

回调函数就是将你想要做的事情写在一个函数中,并把这个函数作为另一个函数的参数交给执行者去执行。举个例子:

                // 回调函数作为参数交给执行者,让执行者决定想什么情况下执行
		function foo(callback) {
			setTimeout(function() {
				callback()
			}, 1000)
		}
		// 回调函数
		function callback() {
			console.log('这是我想要做的事情')
		}
		foo(callback)

Promise

promise初始化

Promise是一个构造函数,promise对象初始化如下:

                // 参数是一个函数,函数里面是你需要执行的函数,并根据结果调用相应的函数,
		// resolve将状态改为resolved,并将结果传给then中的第一个回调函数参数
		// resolve将状态改为rejected,并将结果传给then中的第二个回调函数参数
		const p = new Promise(function(resolve, reject) {
			resolve('success')
		})
		// 不同结果的相应回调函数,成功了执行第一个函数,失败了执行第二个函数
		p.then(res => {
			console.log(res)
		}, err => {
			console.log(err)
		})

用Promise封装Ajax请求:

                function ajax (url) {
			return new Promise((resolve, reject) => {
				const xhr = new XMLHttpRequest()
				xhr.onload = function () {
					if(this.status === 200){
						resolve(this.response)
					}else{
						reject(new Error(this.statusText))
					}
				}
				xhr.responseType = 'json'
				xhr.open('GET', url)
				xhr.send()
			})
		}
		ajax('https://www.ctwing.cn/sysCategory/getCatTreeByCode/homepage_nav').then(res => {
			console.log('success', res)
		}, err => {
			console.log('fail', err)
		})

链式调用

如果一个请求的发起需要在另一个请求成功的基础上,那么如果写在前一个then回调函数中,同样会造成地狱回调的问题。promise提供了链式调用来解决这个问题。

promise.then返回的是一个全新的promise对象(不是像以往的那种return this来实现的)。链式调用时,每一个then方法都在为上一个then返回的promise对象添加回调。

promise.then中也可以手动return一个promise对象作为下一个then方法的promise对象。

异常处理

在链式调用中,如果异常捕获写在.then的第二个参数中,则只能捕获当前promise的异常。如果写在链条的最末端,那么可以捕获到链条上的所有异常,链条上任何一个异常都会被传递,直至被捕获。

静态方法

Promise.resolve() 快速创建一个状态为resolved的promise对象

  • 参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的 Promise 对象
  • 参数是一个 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。
  • 参数是一个有then方法的对象,将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法
  • 参数为空,直接返回一个resolved状态的 Promise 对象,resolvedValue为undefined

Promise.reject() 快速创建一个状态为reject的promise对象

                const p = new Promise((resolve, reject) => {
			resolve('a promise Object')
		})
		const p1 = Promise.resolve('foo')
		 // Promise {<resolved>: "foo"}
			// __proto__: Promise
			// [[PromiseStatus]]: "resolved"
			// [[PromiseValue]]: "foo"
		const p2 = Promise.resolve(p)
		console.log(p2 === p)
		// true 
		const p3 = Promise.resolve({
			name: 'tom',
			then: function (resolve, reject) {
				console.log('name is: ' + this.name)
				resolve(this.name)
			}
		})
		// name is: tom 立即执行then方法
		// Promise {<resolved>: "tom"}
			// __proto__: Promise
			// [[PromiseStatus]]: "resolved"
			// [[PromiseValue]]: "tom"
		const p4 = Promise.resolve()
		// Promise {<resolved>: undefined}
		// 	__proto__: Promise
		// 	[[PromiseStatus]]: "resolved"
		// 	[[PromiseValue]]: undefined

Promise.all() 参数为promise对象数组。返回一个新的promise对象,等待所有结果成功,新对象才返回成功,并将所有的结果传递给新对象,如果其中一个失败,则新对象失败,并返回第一个失败的结果

Promise.race() 返回第一个完成的任务的结果

                const pro1 = new Promise((resolve, reject) => {
			setTimeout(function () {
				resolve('success1')
			}, 1000)
		})
		const pro2 = new Promise((resolve, reject) => {
			setTimeout(function () {
				resolve('success2')
			}, 3000)
		})
		const pro3 = new Promise((resolve, reject) => {
			setTimeout(function () {
				reject('failed1')
			}, 2000)
		})
		const proAll = Promise.all([pro1, pro2])
		// Promise {<resolved>: Array(2)}
			// 	__proto__: Promise
			// 	[[PromiseStatus]]: "resolved"
			// 	[[PromiseValue]]: Array(2)
			// 	0: "success1"
			// 	1: "success2"
			// 	length: 2
			// 	__proto__: Array(0)
		const proRace = Promise.race([pro1, pro2, pro3])
		// Promise {<resolved>: "success1"}
		// 	__proto__: Promise
		// 	[[PromiseStatus]]: "resolved"
		// 	[[PromiseValue]]: "success1"

小练习:带有timeout的请求结果

                function request () {
			return new Promise((resolve, reject) => {
				setTimeout(function () {
					resolve('success')
				}, 2000)
			})
		}
		function timeout () {
			return new Promise((resolve, reject) => {
				setTimeout(function () {
					reject('time out!')
				}, 500)
			})
		}

		const newRequst = Promise.race([request(), timeout()])
		newRequst.then(res => {
			console.log(res)
		}).catch(err => {
			console.log(err)
		})

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值