一、介绍
Promise是一种常用的异步解决方案,解决回调地狱的问题。
Promise可以解决两个问题:
- 对象的状态不受外界影响。
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果。
Promise发送的请求会经历三个过程:padding(进行中)、fullfilled(成功)、rejected(失败)。当状态决定后就不会在改变,这个时候就会把状态改为resolved(已定型)
二、使用
我通常配合vue和axios进行使用。
首先封装axios
import axios from 'axios'
//设置超时时间
axios.defaults.timeout = 10000
//设置请求头
axios.defaults.headers.post['Content-Type']='multipart/form-data; boundary=<calculated when request is sent>'
//请求拦截
axios.interceptors.request.use(
config => {
return config
},
error => {
return Promise.error(error)
}
)
// 响应拦截器
// axios.interceptors.response.use(
// response => {
// // 如果返回状态码200 说明接口请求成功
// console.log(response)
// }
// )
// get方法 对应get请求
// url 请求地址
// params 请求时携带的参数
export function get(url , params){
return new Promise((resolve , reject) => {
axios.get(url,{
params
}).then(res => {
resolve(res.data)
}).catch(err => {
reject(err.data)
})
})
}
// post方法 对应post请求
export function post(url,params){
return new Promise((resolve,reject)=>{
axios.post(url,params).then(res=>{
resolve(res.data)
}).catch(err => {
reject(err.data)
})
})
}
// export function request(state,url,params){
// if(state == "get"){
// return this.get(url,params)
// }else if(state == "post"){
// return this.post(url,params)
// }else{
// return 'error'
// }
// }
然后封装接口
// 暴露接口
import {post} from './http'
// 登录接口
export let sysLogin = (sysuser) => {
let params = new URLSearchParams()
params.append('username',sysuser.username)
params.append('password',sysuser.password)
return post('/customer/sysLogin',params)
}
// 初始化接口
export let initSystem = () =>{
return post("/customer/initSystemuser",{})
}
在组件中调用
methods:{
takelogin(){
let sysuser = new Object()
sysuser.username = this.username
sysuser.password = this.password
// let res = sysLogin(sysuser)
sysLogin(sysuser).then(
res=>{
console.log(res)
console.log(typeof res.message)
console.log(res.message)
if(res.message){
this.$message({
message: '登录成功',
type: 'success'
});
this.$router.push("/page")
}else{
this.$message({
message: '登录失败',
type: 'error'
});
}
}
)
},
initSystem(){
initSystem().then(
res=>{
if(res.message){
this.$message({
message: '初始化成功',
type: 'success'
});
}else{
this.$message({
message: '初始化失败或您已经初始化',
type: 'error'
});
}
}
)
}
},
三、Promise的函数
Promise有以下函数:
let p = new Promise
[1] p.prototype.then()
[2] p.prototype.catch()
[3] p.prototype.finally()
[4] p.all()
[5] p.race()
[6] p.allSettled()
[7] p.any()
[8] p.resolve()
[9] p.reject()
[10] p.try()
[1] p.prototype.then()
then方法是定义在原型对象Promise.prototype上的。
它的作用是为 Promise 实例添加状态改变时的回调函数。
then方法的第一个参数是resolve,第二个是rejected
[2] p.prototype.catch()
catch方法是一个then方法的一个别名,是then(null,rejected)这样的一个状态。
[3] p.prototype.finally()
finally是用于指定不管 Promise 对象最后状态如何,都会执行的操作。
finally方法的回调函数不接受任何参数,导致前面的 Promise 状态到底是fulfilled还是rejected,所以finally方法里面的操作不依赖于 Promise 的执行结果。
不使用finally方法,同样的语句需要为成功和失败两种情况各写一次。有了finally方法,则只需要写一次。
[4] p.all()
Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例
.all()方法的参数是一个Promise数组
当多种Promise的状态不一致时会出现两种现象
·状态都变成fulfilled,p的状态才会变成fulfilled,此刻返回值会变成一个数组返回给p
·多个Promise里存在一个rejected则会导致整体状态成为Promise,并且返回第一个rejected的详细信息。
[5]p.race()
Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
[6] p.allSettled()
Promise.allSettled()方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只有等到所有这些参数实例都返回结果,不管是fulfilled还是rejected,
[7] p.any()
该方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例返回。
只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;
如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。
[8]p.resolve()
有时需要将现有对象转为 Promise 对象,Promise.resolve()方法就起到这个作用。
[9]p.reject()
Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。
[10]p.try()
实际开发中,经常遇到一种情况:不知道或者不想区分,函数f是同步函数还是异步操作,但是想用 Promise 来处理它。
因为这样就可以不管f是否包含异步操作,都用then方法指定下一步流程,用catch方法处理f抛出的错误。
通常"Promise.resolve().then(f) "用这种方式把f变成符合promise的函数,但是如果f是同步函数这就会导致f只会在本段程序的末尾执行,有两种写法可以解决这个问题。
方法一:第一种写法是用async函数来写。
const f = () => console.log('now');
(async () => f())();
console.log('next');
方法二:第二种写法是使用new Promise()。
const f = () => console.log('now');
(
() => new Promise(
resolve => resolve(f())
)
)();
console.log('next');
p.try()就是解决以上的执行方式的痛点Promise.try
为所有操作提供了统一的处理机制,所以如果想用then
方法管理流程,最好都用Promise.try
包装一下。这样有许多好处,其中一点就是可以更好地管理异常。