上一篇文章中,我们知道了Promise是异步编程的一种方案还有使用的基本语法,下面我们来看看Promise的三种状态和链式调用吧 o( ̄︶ ̄)o
一、三种状态
1.pending-等待状态
当浏览器向服务器发送网络请求时,就会处于该状态
2.fulfill-满足状态
当我们主动回调了resolve时,就处于该状态,并且会回调.then()
3.reject-拒绝状态
当我们主动回调了reject时,就处于该状态,并且会回调.catch()
这三种状态大家伙大概了解一下就行 (✿◡‿◡)下面小编通过一张图来进一步为大家分析Promise的执行过程,该图如下所示:
Async operation 代表异步操作,首先会将有关异步处理事件打包好之后发送到Promise内部,这个时候Promise分别会经过下面三个状态:
第一,当向服务器发送的请求不可能立马得到回应,在发送请求和请求得到回应的阶段就是处于Pening等待状态;
第二,当请求回来的数据被成功接收之后,就处于Fulfilled状态,该状态下的Promise会执行resolve函数,然后回调then函数执行相关的请求处理;
第三,当请求被拒绝的时候,就处于reject状态,该状态下的Promise会执行reject函数,然后回调catch函数进行相关的请求处理。
此外,小编在这里向大家伙介绍Promise的另外一种写法:
new Promise((resolve,reject) =>{
setTimeout(()=>{
resolve();
reject()
},1000)
}).then(()=>{
console.log('hello,vue')
},()=>{
console.log('error message')
})
这种写法就是给then传递两个参数,第一个参数是处理请求成功的逻辑,第二个参数是处理请求失败的逻辑,为什么可以这么缩写呢,因为在then的源码中就表示可以传递两个参数,不信我们一起来看看then的源码:
可以看到,有两个状态 onfulfilled 和 onrejected,意思就是当请求成功的时候执行第一个函数的内容,当请求失败的时候执行第二个函数的内容。
以上便是Promise简单的运行过程和三个基本状态,下面我们来看看Promise的链式调用。
二、链式调用
1.链式调用1
这个链式调用呢,很简单,就是上次小编说要给大家伙看的彩蛋,其代码如下:
<script>
new Promise((resolve,reject) =>{
setTimeout(()=>{
resolve()
},1000)
}).then(()=>{
console.log('hello,vue')
return new Promise((resolve,reject) =>{
setTimeout(()=>{
resolve()
},1000)
})
}).then(() =>{
console.log('hello,java')
return new Promise((resolve,reject) =>{
setTimeout(()=>{
resolve()
},1000)
})
}).then(() =>{
console.log('hello,JavaScript')
})
</script>
上述代码的执行步骤是,首先执行resolve函数调用then函数,先执行第一个then函数的打印语句,执行完成之后发现下面还有一个异步事件的操作,然后执行第二个异步事件的resolve函数来调用第二个then函数的打印语句,执行完成之后发现下面还有一个异步事件的操作,然后再次去执行第三个异步事件的resolve函数调用第三个then函数执行打印语句。
这就是链式调用的一种方式,下面小编为大家介绍另外一种方式
2.链式调用2
① 版本一
现在我们有一个需求,当向网络请求数据得到的结果是aaa时,进行两步操作,第一步是自身对别的业务逻辑进行处理,第二是对拿到的结果aaa进行处理,然后不断循环该过程,我们通过链式调用来达到这种目的,具体代码如下:
<script>
new Promise(resolve =>{
setTimeout(()=>{
resolve('aaa')
},1000)
}).then(res =>{
// 1.自己处理别的业务的代码
console.log(res,'第一次自己处理别的业务的代码')
// 2.对拿到的结果进行处理
return new Promise(resolve =>{
resolve(res +'111')
})
}).then(res=>{
console.log(res,'第二次自己处理别的业务的代码')
return new Promise(resolve =>{
resolve(res +'222')
})
}).then(res =>{
console.log(res,'第三次自己处理别的业务的代码')
})
</script>
上述代码中,之所以要将对结果的处理再放到一个Promise中,是因为不想和自己处理别的业务逻辑的代码放在一块,不然容易分辨不清那个模块处理什么内容。
② 版本二
上述的代码还可以进行简化,简化版如下:
new Promise(resolve =>{
setTimeout(()=>{
resolve('aaa')
},1000)
}).then(res =>{
console.log(res,'第一次自己处理别的业务的代码')
return Promise.resolve(res +'111')
}).then(res=>{
console.log(res,'第二次自己处理别的业务的代码')
return Promise.resolve(res +'222')
}).then(res =>{
console.log(res,'第三次自己处理别的业务的代码')
})
只是将上述代码中对结果处理的Promise进行了简化,不需要通过new Promise 的方式来获取resolve函数,而是直接通过Promise.resolve()的方式来获取。
③ 版本三
另外还有一个更加简化版的,具体代码如下:
new Promise(resolve =>{
setTimeout(()=>{
resolve('aaa')
},1000)
}).then(res =>{
console.log(res,'第一次自己处理别的业务的代码')
return res +'111'
}).then(res=>{
console.log(res,'第二次自己处理别的业务的代码')
return res +'222'
}).then(res =>{
console.log(res,'第三次自己处理别的业务的代码')
})
这次的代码是直接将Promise.resolve都省略了,让他们内部自己运行Promise.resolve()。三个简化版的结构是一样的,这里就不展示出来了。
另外还有一个需要注意的问题,如果是调用了reject函数,会直接跳转去执行catch函数,中间的代码就不会被执行了,比如:
new Promise(resolve =>{
setTimeout(()=>{
resolve('aaa')
},1000)
}).then(res =>{
console.log(res,'第一次自己处理别的业务的代码')
return Promise.reject(res +'111')
}).then(res=>{
console.log(res,'第二次自己处理别的业务的代码')
return Promise.resolve(res +'222')
}).then(res =>{
console.log(res,'第三次自己处理别的业务的代码')
}).catch(()=>{
console.log('error')
})
好了,以上就是今天的小内容啦,总结如下:
1.三种状态
2.链式调用的两种方式
3.链式调用方式的简化版
今天的小编也是棒棒哒,你觉得呢 ⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄
如果同意就给小编点个赞吧,ღ( ´・ᴗ・` )比心❤