feach
1、xhr
windows自带的xhmlHttpRequest请求
xhr是Ajax通过异步刷新请求获取数据,来实现部分数据进行更新
不关注分离
// 新建一个XMLHttpRequest实例 var xhr = new XMLHttpRequest(); // 然后,向远程主机发出一个HTTP请求 xhr.open('GET', 'example.php'); xhr.send(); // 待远程主机做出回应。这时需要监控XMLHttpRequest对象的状态变化,指定回调函数 xhr.onreadystatechange = function(){ if ( xhr.readyState == 4 && xhr.status == 200 ) { alert( xhr.responseText ); } else { alert( xhr.statusText ); } } // ...
2、jquery
封装后的xhr,每次请求,都是通过回调函数来返回成功、失败的请求,容易造成回调地狱
包体积比较大,如果需要另外引入不建议使用
3、axios
轻量级,建议使用
封装了xhr对象的Ajax(前端)
promise风格,能解决回调地狱
可以在浏览器和node 服务器端
并且设置的有拦截器
4、fetch
和XHR并列,window内置,直接可以用
4.1开始测试
fetch(`/api/search/users?q=${value}`).then( result =>{console.log("联系服务器成功了",result)}, error =>{console.log("联系服务器失败了",error)} )
// 联系服务器成功图片(我们可以发现下面图片中没有返回任何数据)
// 当请求服务器出现不可抗力的因素的时候,假如我们让网络处于断网状态,这个时候走的是失败的路线
当我们路径有问题时候
fetch(`/api/search/users222?q=${value}`).then(
result =>{console.log("联系服务器成功了",result)},
error =>{console.log("联系服务器失败了",error)}
)
// 返回结果,如下图所示,我们可以发现,这个请求走的依旧是成功的路子,即联系服务器成功,但是它的状态码是404,也就是说,当我们发送请求时候,请求联系服务器是成功的,但是服务器不认识我,所以返回状态码是404
经过上述探讨,我们发现当,联系服务器成功时候,成功的回调中有个Prototype对象,里面有个json()方法,当我们打印这个方法,就可以看见它返回的依然是一个Promise实例 (我们需要的数据在这里面)
fetch(`/api/search/users?q=${value}`).then( result =>{console.log("联系服务器成功了",result.json())}, error =>{console.log("联系服务器失败了",error)} )
4.2 既然我们发现返回的结果是Promise实例,我们就可以继续链式回调,
fetch(`/api/search/users?q=${value}`).then( result => { console.log("联系服务器成功了"); return result.json();//返回结果是一个Promise实例 }, error =>{console.log("联系服务器失败了",error)} ).then( result =>{console.log("成功了",result)}, error =>{console.log("失败了",error)} )
这个时候,获取的结果:
但是这样做有一个弊端,当我们因为一些不可抗力的原因,例如断网了,导致联系服务器失败,这个时候我们再来看一下调用上面代码的结果:
我们可以看见,当离线了,服务器链接失败—>成功了,返回结果是undefined
这是因为,连接服务器失败了,失败了任然有一个返回值,而且返回的还是一个非Promise实例,那么上面的这个.then就默认是成功的,下面的.then 就走的是成功的回调函数,结果是undefined;
4.3 所以我们想让连接服务器失败就直接中断,不继续往下走;
继续优化上面代码:
fetch(`/api/search/users?q=${value}`).then( result => { console.log("联系服务器成功了"); return result.json(); }, error =>{ console.log("联系服务器失败了",error); // 返回一个初始化(Pending)状态的Promise对象,应为其它两个值都会继续往下走 return new Promise(()=>{}); } ).then( result =>{console.log("成功了",result)}, error =>{console.log("失败了",error)} )
然后,我们再继续上面的测试:因为一些不可抗力的原因,例如断网了,导致联系服务器失败,这个时候我们再来看一下调用上面代码的结果:
我们发现直接是联系服务器失败,没有继续往下走
4.4 继续优化:
我们发现上面代码中,两个.then中有两个失败的回调(error),然后Promise实例可以统一处理错误
fetch(`/api/search/users?q=${value}`).then( result => { console.log("联系服务器成功了"); return result.json(); }).then( result =>{console.log("成功了",result)} ).catch( error => {console.log("出错了",error)} )
4.5 继续优化:
然后我们发现上面还有可以优化的空间,即async await, await右边一定是Promise实例;
search = async () => { // 获取输入框中数据 const {value} = this.inputworlds; // TODO let response = await fetch(`/api/search/users?q=${value}`); let data = await response.json(); console.log(data) }
注意:await返回的是一个成功的结果,异常不管,所以继续优化
search = async () => { // 获取输入框中数据 const {value} = this.inputworlds; // TODO try { let response = await fetch(`/api/search/users?q=${value}`); let data = await response.json(); console.log(data) } catch (error) { console.log("error",error.message); } }