0%

fetch/async/await

fetch和await的结合

起因是在写一个React发送ajax请求的案例中,遇到了一个关于fetch发送请求的问题,直接上代码:

使用fetch发送请求后在第一个.then之前的fetch(https:xxxx//${value})返回的是一个promise实例对象,所以它的后面可以跟.then,但是这个.then中触发的成功回调或者失败回调仅仅是判断这个请求是否连接到服务器,并不会返回服务器发送回来的数据。

要想得到数据就需要调用res原型上的方法res.json()得到一个新的promise,并且return出去,紧跟后面的.then就可以采用链式.then的方法再次获得成功的回调(服务器返回的数据在里面)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  search = ()=>{
// 使用fetch发送网络请求(未优化版本)
fetch(`https://api.github.com/search/users?q=${value}`).then(
res=>{
console.log('联系服务器成功');
return res.json();
},
// error=>{
// console.log('联系服务器失败');
// // 如果第一个then没有返回值,那么它会返回一个undefined,
// // 而undefined所在的.then返回的promise则是一个成功状态的promise
// // 使用return new Promise();返回一个初始状态的Promise实例,则下面的then则不会走了
// return new Promise();
// }
).then(
ress=>{
// console.log(ress.items);
PubSub.publish('change',{isFirst:false,users:ress.items,isLoading:false})
},
// error=>{
// console.log('获取数据失败');
// PubSub.publish('change',{isFirst:false,err:error.message})
// }
).catch((error)=>{
console.log(error);
})
}

当然可以不用每个.then都捕获错误回调,可以在结尾统一拦截错误使用.catch()

还有一个小bug就是,如果在第一个.then中的错误回调没有返回一个promise或者其他什么的,他会默认返回undefined,而这个undefined则代表其所在.then返回的是一个成功状态的promise,这就导致后面的.then执行的是成功回调。


然后再说说async和await优化版本:

使用async和await可以更大限度优化代码,

等待fetch(https://api.github.com/search/users?q=${value})返回一个成功态promise给response,response接收到后调用它原型上的方法response.json()当然也要等待它返回一个成功态promise,并将其赋值给data,此时的data就是服务器返回的真正数据

另外,捕获错误可以使用try-catch捕获错误

这种写法可以使用同步执行的思考来看待这个请求,对于promise的理解更深一步加强

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
search = async ()=>{
// 解构赋值的连续写法
// keyWordElement是未被定义的
const {keyWordElement:{value}}=this
// 发送请求前通知List更新状态
PubSub.publish('change',{isFirst:false,isLoading:true})//不用关注

try {
const response = await fetch(`https://api.github.com/search/users?q=${value}`)
const data = await response.json();
// console.log(data);//服务器返回的真正数据
PubSub.publish('change',{isFirst:false,users:data.items,isLoading:false})
} catch (error) {
console.log('请求出错',error);
PubSub.publish('change',{isFirst:false,err:error.message})
}
}