Promise含义
Promise是一种异步编程的解决方案,它可以获得异步操作的消息。
promise有三种状态:pending(进行中)、fullfilled(已成功)、reject(已失败)。只有异步操作的结果才能决定promise的状态。
Promise 操作
在promise出现以前,假设我们需要输出fn1的结果后的一秒输出fn2的结果,然后再输出fn3的结果,我们需要这样操作。
function fn1(callback) {
setTimeout(()=>{
console.log('fn1')
callback()
}, 1000)
}
function fn2(callback) {
setTimeout(()=>{
console.log('fn2')
callback()
}, 1000)
}
function fn3() {
setTimeout(()=>{
console.log('fn3')
}, 1000)
}
然后进行调用:
fn1(
function(){
fn2(
function(){
fn3()
})
})
如果层级很多的话,比如下面这种:
![](https://img.haomeiwen.com/i12302412/9468ce3129787982.png)
这种回调函数的嵌套,由于嵌套层次太多,我们称之为“回调地狱”。
使用promise可以很好的解决这种情况,我们可以做如下改造:
function fn1() {
return new Promise((resolve, reject)=>{
setTimeout(()=>{
console.log('fn1...')
resolve()
}, 1000)
})
}
function fn2() {
return new Promise((resolve, reject)=>{
setTimeout(()=>{
console.log('fn2...')
resolve()
}, 1000)
})
}
function fn3() {
return new Promise((resolve, reject)=>{
setTimeout(()=>{
console.log('fn3...')
resolve()
}, 1000)
})
}
function error () {
console.log('error')
}
然后进行调用:
fn1().then(fn2).then(fn3).catch(error)
![](https://img.haomeiwen.com/i12302412/a7224b8617056df1.png)
这样就很好的解决了“回调地狱”问题,代码变得更加清晰,可读性更好。
promise的一个更加重要的作用是可以让我们在异步像同步函数一样获取return的值。
比如我们手机上的外卖软件,它是先获取我们手机的ip地址,通过ip地址来取得城市的名称,然后返回我们附近的商家信息。
function getIp() {
let promise = new Promise(function(resolve, reject){
let xhr = new XMLHttpRequest()
xhr.open('GET', 'url/api/ip', true)
xhr.onload = function(){
var retJson = JSON.parse(xhr.responseText)
resolve(retJson.ip)
}
xhr.onerror = function(){
reject('获取IP失败')
}
xhr.send()
})
return promise
}
function getCity(ip){
let promise = new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest()
xhr.open('GET', 'url/api?ip='+ip, true)
xhr.onload = function(){
let retJson = JSON.parse(xhr.responseText)
resolve(retJson.city)
}
xhr.onerror = function(){
reject('获取city失败')
}
xhr.send()
})
return promise
}
function getShopsFromCity(city) {
var promise = new Promise(function(resolve, reject){
let xhr = new XMLHttpRequest()
xhr.open('GET', 'url/api/shops?city='+city, true)
xhr.onload = function(){
var retJson = JSON.parse(xhr.responseText)
resolve(retJson)
}
xhr.onerror = function(){
reject('获取周边商家失败')
}
xhr.send()
})
return promise
}
getIp().then((ip)=>{
return getCity(ip)
}.then((city)=>{
return getShopsFromCity(city)
}).then((res)=>{
console.log(res)
}
}
这样我们就可以获得商家信息了,通过promise很好的解决了return的问题。
promise常用函数
all
当前的promise对象都执行完以后再进行操作
Promise.all([p1, p2, p3]).then(data=>{
console.log(data)
})
race
当前的promise对象,只要其中一个状态改变,那个率先改变的值就传给回调函数。
Promise.race([p1, p2, p3]).then(data=>{
console.log(data)
})
通过promise封装axios操作
在实际开发中,我们通常使用axios这个基于promise的HTTP库,来创建浏览器的XMLHttpRequst。如果每次都像下面这样使用,代码会非常繁琐:
axios.get('/api/home?page=' + page).then((res) => {
const result = res.data.data
const action = addHomeList(result, page+1)
dispatch(action)
})
首先我们先定义axios的一些常用属性
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
axios.defaults.baseURL = baseURLConfig.baseURL
axios.defaults.withCredentials = true
然后export default 一个默认是”GET“请求的request函数
export default function request(url, type = 'GET', data = {}) {
return new Promise((resolve, reject) => {
let option = {
url,
method: type,
validateStatus (status) {
return (status >= 200 && status < 300) || status === 400
}
}
if (type.toLowerCase() === 'get') {
option.params = data
} else {
option.data = data
}
axios(option).then(res =>{
if (res.status === 200) {
resolve(res.data)
} else {
reject(res.data)
}
}).catch(err=>{
reject({msg: '网络异常:'+ err})
})
})
}
然后在组件中,就可以像下面这样使用了,代码可读性更好了
request(url,type,{}).then((res)=>{ console.log(res.data) })
.catch(err=>{
console.log(error)
})
网友评论