Promise
什么是 Promise
Promise 是一个对象,对象里存储一个状态,这个状态是可以随着内部的执行转化的,为以下三种状态之一:等待态(Pending)、完成态(Fulfilled)、拒绝态(Rejected)。
一开始,我们先设置好等状态从 pending 变成 fulfilled 和 rejected 的预案(当成功后我们做什么,失败时我们做什么)。
Promise 启动之后,当满足成功的条件时我们让状态从 pending 变成 fullfilled (执行 resolve);当满足失败的条件,我们让状态从 pending 变成 rejected(执行 reject)
Promise 的用法
一个getip()
getCityFromIp(ip) 通过ip获取城市的名字
getWeatherFromCity(city) 通过城市的名字获取城市的天气
之前只能用回调,
Promise.prototype.then / Promise.prototype.catch
Promise.all
var p1 = getCityFromIp('10.10.10.1')
var p2 = getCityFromIp('10.10.10.2')
var p3 = getCityFromIp('10.10.10.3')
//Promise.all, 当所有的 Promise 对象都完成后再执行
Promise.race([p1, p2, p3]).then(data=>{
console.log(data)
})
Promise.race
对于开头回调地狱的解决
样式
function fn(){
return new Promise((resolve,reject)=>{
成功时调用resolve()
失败时调用reject()
})
}
fn().then(success,fail).then(success2,fail2)
解决
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 onerror() {
console.log('error')
}
fn1().then(fn2).then(fn3).catch(onerror)
引入axois,使用Promise进行封装成统一接口
axois 来源于axois的文档
// `validateStatus` defines whether to resolve or reject the promise for a given
// HTTP response status code. If `validateStatus` returns `true` (or is set to `null`
// or `undefined`), the promise will be resolved; otherwise, the promise will be
// rejected.
validateStatus: function (status) {
return status >= 200 && status < 300; // default
},
实战:
//request.js
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
axios.defaults.baseURL = baseURLConfig.baseURL
axios.defaults.withCredentials = true
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 {
console.error(res.data)
reject(res.data)
}
}).catch(err => {
console.error({ msg: '网络异常' })
reject({ msg: '网络异常' })
})
})
}
Login 组件使用 Auth接口
//Login.vue
import request from "@/helpers/request";
request("/auth/login", "POST", { username: "hunger", password: "123456" }).then(
(data) => {
console.log(data);
}
);
//Sidebar.vue
<script>
import request from "@/helpers/request";
export default {
components: {
avatar,
},
methods: {
logout() {
console.log("logout");
request("/auth/logout").then((data) => {
console.log(data);
});
},
},
};
</script>
request("/auth/register", "POST", {
username: this.register.name,
password: this.register.password,
}).then((data) => {
console.log(data);
});
request("/auth/login", "POST", {
username: this.login.name,
password: this.login.password,
}).then((data) => {
console.log(data);
});
解决跨域问题
//request.js
withCredentials: true, //允许跨域请求
接口封装成API
//auto.js
//统一在这里封装接口成函数
const URL = {
REGISTER: '/auth/register',
LOGIN: '/auth/login',
LOGOUT: '/auth/logout',
GET_INFO: '/auth'
}
export default {
register({ username, password }) {
return request(URL.REGISTER, 'POST', { username, password })
},
login({ username, password }) {
return request(URL.LOGIN, 'POST', { username, password })
},
logout() {
return request(URL.LOGOUT)
},
getInfo() {
return request(URL.GET_INFO)
}
}
Auth.login({
username: this.login.name,
password: this.login.password,
}).then((data) => {
console.log(data);
});
生产环境和开发环境baseURL 无缝切换
在build下配置mock.config.js 和webpack.dev.conf.js
1.定义两个变量mockBaseURL和realBaseURL,并设置isDev默认为true\
2.,mockBaseURL中isDev为true,realBaseURL中isDev为false\
3.webpack.dev.config.js文件中添加require('./mock.config').config({isDev:true})\
4.webpack.prod.config.js文件中添加require('./mock.config').config({isDev:false})\
5.在开发环境时调用mockBaseURL\
6.在生成环境时调用realBaseURL