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);
    }
  }
posted @ 2021-11-24 10:42  一江春水向东刘小姐  阅读(190)  评论(0编辑  收藏  举报