Promise主要解决异步深层嵌套的问题
Promise 提供了简洁的API,使得异步操作更加容易
从语法上讲,Promise是一个对象,也是一个函数
我们使用new来构建一个Promise,并且传入两个参数: resolve,reject
分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数:
var p = new Promise(function(resolve, reject){
// 这里用于实现异步任务
setTimeout(function(){
var flag = false;
if(flag) {
// 正常情况
resolve('hello');
}else{
// 异常情况
reject('出错了');
}
}, 100);
});
Promise实例生成以后,可以用then方法指定resolved状态和reject状态的回调函数:
p.then(function(data){
console.log(data)
},function(info){
console.log(info)
});
function queryData(url) {
// 创建一个Promise实例
var p = new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState != 4) return;
if(xhr.readyState == 4 && xhr.status == 200) {
# 处理正常的情况
resolve(xhr.responseText);
}else{
# 处理异常情况
reject('服务器错误');
}
};
xhr.open('get', url);
xhr.send(null);
});
return p;
}
// 注意: 这里需要开启一个服务
// 在then方法中,你也可以直接return数据而不是Promise对象,在后面的then中就可以接收到数据了
queryData('http://localhost:3000/data')
.then(function(data){
console.log(data)
// 当需要发送多个ajax请求并且保证顺序时,要使用链式编程,需要 return
return queryData('http://localhost:3000/data1');
})
.then(function(data){
console.log(data);
return queryData('http://localhost:3000/data2');
})
.then(function(data){
console.log(data)
});
.then() 得到异步任务正确的结果
.catch() 获取异常信息
.finally() 成功与否都会执行(不是正式标准)
.all():Promise.all 方法接受一个数组作参数,数组中的对象(p1、p2、p3)均为promise实例,当所有的Promise对象都完成以后才会返回
.race():Promise.race 方法同样接受一个数组作参数,与all方法不同的是,只要有其中一个Promise对象完成就会返回
使用示例:
Promise.all([p1,p2,p3]).then(function(result){
console.log(result)
})
Promise.race([p1,p2,p3]).then(function(result){
console.log(result)
})
Fetch API是新的ajax解决方案,更好的封装了ajax代码
//fetch的第一个参数是请求路径,Fetch会返回Promise对象,所以我们还要使用then才能拿到请求成功的结果
fetch('http://localhost:3000/fdata').then(function(data){
// text()方法属于fetchAPI的一部分,它返回一个Promise实例对象,用于获取后台返回的数据
return data.text();
}).then(function(data){
// 在这个then里面我们能拿到最终的数据
console.log(data);
})
使用fetch请求时,也要遵循HTTP协议,请求方式有POST,GET,DELETE,UPDATE,PATCH和PUT,默认的是 GET 请求
使用fetch时需要在 options 对象中 指定对应的 method 请求方式
不同的请求方式,参数传递的格式也不同
//GET参数通过 /值 的形式传递,即 id = 456
fetch('http://localhost:3000/books/456', {
// get 请求可以省略不写 默认的是GET
method: 'get'
})
.then(function(data) {
return data.text();
}).then(function(data) {
console.log(data)
});
使用post请求传参时需要在options中设置请求头 headers 和 body
fetch('http://localhost:3000/books', {
method: 'post',
body: JSON.stringify({
uname: '张三',
pwd: '456'
}),
headers: {
'Content-Type': 'application/json'
}
})
.then(function(data){
return data.text();
}).then(function(data){
console.log(data)
});
Fetch响应结果的数据格式有两种,一种为text,一种为json
text返回的数据格式为字符串string
json返回的数据格式为对象obj
axios是基于promise的用于浏览器和node.js的http客户端
axios能拦截请求和响应,能自动转换JSON数据,也能转换请求和响应数据
// 通过传统的url 以 ? 的形式传递参数
axios.get('http://localhost:3000/axios?id=123').then(function(ret){
console.log(ret.data)
})
// 通过restful 形式传递参数
axios.get('http://localhost:3000/axios/123').then(function(ret){
console.log(ret.data)
})
// 通过params 形式传递参数
axios.get('http://localhost:3000/axios', {
params: {
id: 789
}
}).then(function(ret){
console.log(ret.data)
})
注意:data属性是固定的用法,用于获取后台的实际数据
// 通过选项传递参数
axios.post('http://localhost:3000/axios', {
uname: 'lisi',
pwd: 123
}).then(function(ret){
console.log(ret.data)
})
// 通过 URLSearchParams 传递参数
var params = new URLSearchParams();
params.append('uname', 'zhangsan');
params.append('pwd', '111');
axios.post('http://localhost:3000/axios', params).then(function(ret){
console.log(ret.data)
})
// 配置公共的请求URL
axios.defaults.baseURL = 'https://api.example.com';
// 配置超时时间
axios.defaults.timeout = 2500;
// 配置公共的请求头
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// 配置公共的post的 Content-Type
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
请求拦截器的作用是在请求发送前进行一些操作
例如在每个请求体里加上token,统一做了处理如果以后要改也非常容易
axios.interceptors.request.use(function(config) {
// 任何请求都会经过这一步 在发送请求之前做些什么
config.headers.mytoken = 'nihao';
// 这里一定要return 否则配置不成功
return config;
}, function(err){
// 对请求错误做点什么
console.log(err)
})
响应拦截器的作用是在接收到响应后进行一些操作
例如在服务器返回登录状态失效,需要重新登录的时候,跳转到登录页
axios.interceptors.response.use(function(res) {
//在接收响应后做些什么
var data = res.data;
return data;
}, function(err){
//对响应错误做点什么
console.log(err)
})
async作为一个关键字放到函数前面,任何一个 async 函数都会隐式返回一个 promise对象
await 关键字只能在使用 async 定义的函数中使用
await后面可以直接跟一个 Promise实例对象
使用示例(使用axios):
axios.defaults.baseURL = 'http:localhost:3000';
async function queryData() {
var ret = await axios.get('adata');
return ret.data;
}
queryData().then(function(data){
console.log(data)
})
使用示例(直接跟Promise实例对象):
async function queryData() {
var ret = await new Promise(function(resolve, reject){
setTimeout(function(){
resolve('nihao')
},1000);
})
return ret;
}
使用示例:
axios.defaults.baseURL = 'http://localhost:3000';
async function queryData() {
var info = await axios.get('async1');
var ret = await axios.get('async2?info=' + info.data);
return ret.data;
}