1 什么时候使用Promise
解决异步请求冗余这样的问题,promise就是用于封装异步请求的。
2 Promise对象
new Promise((resolve, reject) => {})
Promise对象的参数是一个函数(resolve, reject) => {}
,这个函数又有2个参数分别是resolve
和reject
。这2个参数本身也是函数,是不是有点绕?后面还有回调函数then(func)
的参数也是一个函数。
模拟定时器的异步事件
用定时器模拟网络请求,定时一秒为网络请求事件,用console.log()表示需要执行的代码。
//1.使用setTimeout模拟嵌套的三次网络请求 setTimeout(() => {//第一次请求 console.log("hello world")//第一次处理代码 setTimeout(() => {//第二次请求 console.log("hello vuejs")//第二次处理代码 setTimeout(() => {//第三次请求 console.log("hello java")//第三次处理代码 }, 1000) }, 1000) }, 1000)
一层套一层,看起是不是很绕。
使用promise来处理异步操作
//参数 -> 函数 // resolve和reject本身也是函数 //then()的参数也是一个函数 new Promise((resolve, reject) => { setTimeout(() => {//第一次网络请求 resolve() }, 1000) }).then(() => { console.log("hello world")//第一次处理代码 return new Promise((resolve, reject) => { setTimeout(() => {//第二次网络请求 resolve() }, 1000).then(() => { console.log("hello vuejs")//第二次处理代码 return new Promise((resolve, reject) => { setTimeout(() => {//第三次网络请求 resolve() }, 1000) }).then(() => { console.log("hello java")//第三次处理代码 }) }) }) })
是不是觉得代码还要更复杂了?仔细看看第一个如果使用了多个就找不到对应关系了。相反第二个流程就很清楚,调用resolve()
就能跳转到then()
方法就能执行处理代码,then()
回调的返回值又是一个Promise
对象。层次很明显,只要是then()
必然就是执行处理代码,如果还有嵌套必然就是返回一个Promise对象,这样调用就像java中的StringBuffer的append()方法一样,链式调用。
new Promise((resolve, reject) => { setTimeout(() => { resolve('success') }, 1000).then(success => { console.log(success) }) })
setTimeout()模拟的是网络请求,而then()执行的是网络请求后的代码,这就将网络请求和请求得到响应后的操作分离了,每个地方干自己的事情。在resolve中传参了,那么在then()方法中的参数就有这个参数,例如data。
网络请求中也会有失败情况?例如网络堵塞。
如何处理失败情况,此时就要用到reject()
new Promise((resolve, reject) => { setTimeout(() => { reject('error message') }, 1000).catch(error => { console.log(error) }) })
此时reject(error)
,catch()
方法捕获到reject()
中的error。
合起来
new Promise((resolve, reject) => { setTimeout(() => { // 成功的时候调用resolve() // resolve('hello world') // 失败的时候调用reject() reject('error message') }, 1000).then(success => { console.log(success) }).catch(error => { console.log(error) }) })
拿ajax来举例子:
new Promise((resolve, reject) => { $.ajax({ success:function(){ // 成功的时候调用resolve() // resolve('hello world') // 失败的时候调用reject() reject('error message') } }).then(success => { console.log(success) }).catch(error => { console.log(error) }) })