引言
promise
目的
为异步操作提供统一接口,解决回调地狱问题,用链式调用的方式执行回调函数
基本事例
//做饭
function cook(){
console.log('开始做饭。');
var p = new Promise(function(resolve, reject){ //做一些异步操作
setTimeout(function(){
console.log('做饭完毕!');
resolve('鸡蛋炒饭');
}, 1000);
});
return p;
}
//吃饭
function eat(data){
console.log('开始吃饭:' + data);
var p = new Promise(function(resolve, reject){ //做一些异步操作
setTimeout(function(){
console.log('吃饭完毕!');
resolve('一块碗和一双筷子');
}, 2000);
});
return p;
}
function wash(data){
console.log('开始洗碗:' + data);
var p = new Promise(function(resolve, reject){ //做一些异步操作
setTimeout(function(){
console.log('洗碗完毕!');
resolve('干净的碗筷');
}, 2000);
});
return p;
}
// 开始调用
cook()
.then(function(data){
return eat(data);
})
.then(function(data){
return wash(data);
})
.then(function(data){
console.log(data);
});
// 或者如下方法调用
cook()
.then(eat)
.then(wash)
.then(function(data){
console.log(data);
});
// 输出
开始做饭
做饭完毕
开始吃饭:鸡蛋炒饭
吃饭完毕
开始洗碗:一块碗和一双筷子
洗碗完毕
干净的碗筷
状态转移
- promise对象返回promise对象
- promise对象有三种状态:初始-挂起(pending)、成功态(fulfilled)、失败态(rejected);后两者称为就绪(settled);
- 当reject()或者resolve()异步操作执行后,状态发生改变,初始状态转变为成功或者失败状态,注意reject和resolve是竞争关系;在成功和失败状态里再调用promise对象重置为pending态
基本api
let p = new Promise(function(resolve,reject){
// 异步请求
resolve('successCallbackData');
reject('failCallbackData');
})
// 链式回调写法
p.then(function(data){
console.log(data) // successCallbackData
},function(data){
console.log(data) // failCallbackData
});
<!--以上代码只会输出successCallbackData,因为异步请求resolve返回后,promise的状态已经改变,后一句reject不会执行了-->
// then的第二个失败回调也可以用catch链式使用
p.then(data=>{console.log(data)}).catch(data=>{console.log(data)});
// then可以只处理失败回调
p.then(null/undefined,data=>{console.log(data)})
// 简写
Promise.resolve(value);
//等同于以下代码
new Promise(function(resolve){
resolve(value);
});
promise对象方法
- resolve 方法把 Promise 的状态置为完成态(Resolved),这时 then 方法就能捕捉到变化,并执行“成功”情况的回调
- reject 方法就是把 Promise 的状态置为已失败(Rejected),这时 then 方法执行“失败”情况的回调(then 方法的第二参数)
- catch 方法除去失败回调,还可以用来:当then的第一个函数抛出错误,会跳到catch中
- all 方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回
- race 的话只要有一个异步操作执行完毕,就立刻执行 then 回调
p.all([p1,p2]).then(data=>{console.log(data)});
p.race([p1,p2]).then(data=>{console.log(data)});
race使用场景
参数数组中设置一个超时计时器,用来对超时请求进行处理
let p2 = function() {
let p = new promise((resolve,reject)=>{
setTimeout(()=>{
reject('超时了');
},5000)
})
}
p.race([p1,p2]).then(data=>{console.log(data)});
Fetch
实例
// jquery ajax
$.ajax({
url: send_url,
data: send_data,
type: 'get',
dataType: 'json',
success:function(){},
error:function(){}
})
// Fetch方式
fetch(url).then(response => response.json())
.then(data => console.log(data))
.catch(e => console.log("Oops, error", e))
API详解
fetch(url, options).then(function(response) {
// handle HTTP response
}, function(error) {
// handle network error
})
1. options属性
- method(String): HTTP请求方法,默认为GET
- body(String): HTTP的请求参数
- headers(Object): HTTP的请求头,默认为{}
- credentials(String):默认为omit,忽略的意思,也就是不带cookie;还有两个参数,same-origin,意思就是同源请求带cookie;include,表示无论跨域还是同源请求都会带cookie
- mode:"cors"参数用来实现cors跨域;"no-cors"不跨域
2. response属性
- status(number): HTTP返回的状态码,范围在100-599之间
- statusText(String): 服务器返回的状态文字描述,例如Unauthorized,上图中返回的是Ok
- ok(Boolean): 如果状态码是以2开头的,则为true
- headers: HTTP请求返回头
- body: 返回体,这里有处理返回体的一些方法
- text(): 将返回体处理成字符串类型
- json(): 返回结果和 JSON.parse(responseText)一样
- blob(): 返回一个Blob,Blob对象是一个不可更改的类文件的二进制数据
- arrayBuffer()
- formData()
缺点
- 不支持IE,需要配合Fetch的一些polyfill来支持Fetch-ie8
- cookie传递
必须在header参数里面加上credientials:'include',才会如xhr一样将当前cookies带到请求中去 - fetch和xhr区别
- fetch虽然底层,但是还是缺少一些常用xhr有的方法,比如能够取消请求(abort)方法
- fetch 在服务器返回4xx、5xx时是不会抛出错误的,这里需要手动通过,通过response中的ok字段和status字段来判断
Axios
通过npm引入的包,是对ajax的封装,可以使用promise语法
基础实例
<!--get请求-->
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
<!--post请求-->
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
axios API
以axios(config)为例
// 发送 POST 请求
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
});
<!--相应别名:-->
axios.post(url[, data[, config]])
配置解构
config对象内容
{
url:'xxx',
method:'get',
params:{id:2234},
data:{},
...
}
响应结构
{
// `data` 由服务器提供的响应
data: {},
// `status` 来自服务器响应的 HTTP 状态码
status: 200,
// `statusText` 来自服务器响应的 HTTP 状态信息
statusText: 'OK',
// `headers` 服务器响应的头
headers: {},
// `config` 是为请求提供的配置信息
config: {}
}
评论 0
还没有评论,来抢个沙发吧。