当前位置:   article > 正文

fetch请求理解和用法_fetch 请求 是异步还是同步

fetch 请求 是异步还是同步

fetch请求

  • fetch请求使用ES6新增语法–Promise:Promise是一个对象,从它可以获取异步操作的消息,原型上有then、catch等方法,可以对结果进行链式调用而不是用传统的回调函数,这使得代码更加简洁。(Promise语法非常重要)
基本用法

fetch请求默认发出 GET 请求,无论请求成功还是失败,都会返回一个 Promise 对象
基本请求方式

var res = fetch('http://jsonplaceholder.typicode.com/posts')  //这个url是可以访问的,可以作为测试url
  • 1

返回的结果
image
可以看到执行成功时状态会变成fulfilled;再看看value字段:value中是Response 对象(response是一个 Stream 对象)
image

接着我们调用Promise原型上的公有方法then(), then方法接收两个函数作为参数,第一个参数是 Promise 执行成功时的回调函数resolve,(resolve函数的参数就是Response 对象,所以要明白then方法中的res其实就是Response),第二个参数是 Promise 执行失败时的回调函数reject,两个函数只会有一个被调用。

fetch("http://jsonplaceholder.typicode.com/posts")
.then(res => res.json())
  • 1
  • 2

Response(res)的json()方法接收一个流,是一个异步操作,取出所有内容,解析为json对象,方便我们调用里面的数据,如果我们打印一下res.json()会得到如下结果
image
再接下来我们继续调用Promise原型上的公有方法then()并打印结果,得到一个数组,因为我们打印的是经过解析的结果,不再是一个Promise对象。
注意:如果我们在第一个方法then()中打印了(即res => {console.log(res.json());})那么再次调用方法then()打印data会显示undefined!!!

fetch("http://jsonplaceholder.typicode.com/posts")
.then(res => res.json())
.then(data => {console.log(data);})
.catch((err) =>{ console.log(err);})    //执行结果是 reject就调用catch方法
  • 1
  • 2
  • 3
  • 4

image
上面的catch方法是与方法then并行的,用来捕获异常的,指定失败的回调(一般我们都会打印一下这个异常)

接下来我们分析Response 对象

从上面的图可知,fetch 请求成功后,会返回 response 对象,在这个对象中存储着响应的信息

  • Response.body属性:响应体,返回一个 ReadableStream 对象,可以用来分块读取内容,response.body.getReader() 返回一个遍历器,这个遍历器 read() 方法每次都会返回一个对象,表示本次读取的内容块(在另一篇文章里 https://www.cnblogs.com/rain111/p/16566501.html 有用到这个方法);
  • Response.headers: 响应头,它是同步属性,可以立即读取;
  • Response.ok属性:布尔值,表示请求是否成功,表明响应是否成功(状态码在200-299范围内表示成功);
  • Response.redirected属性: 布尔值,表示是否发生过跳转;
  • Response.status属性: 响应的状态代码,它是同步属性,可以立即读取(例如,成功为200);
  • Response.statusText属性: 服务器返回状态文字描述,它是同步属性,可以立即读取;
  • Response.url属性:请求的 URL。(如果 URL 存在跳转,该属性返回的是最终 URL);
  • Response.type属性:请求的类型。可能的值如下:
    • basic:同源请求
    • cors:跨域请求(本例就是)
    • error:网络错误。

注意:fetch()发起请求以后,只有网络错误,或者无法连接时,fetch()才会报错,其他情况都认为请求成功。所以我们为您一般通过Response.status属性得到 HTTP 回应的真实状态码或者判断response.ok是否为true,来判断请求是否成功.

fetch("http://jsonplaceholder.typicode.com/posts")
.then(res => {
    if (res.ok) {
       return res.json()
    }
})
.then(data => console.log(data))
.catch(err => console.log(err))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
读取Response内容的方法(异步,返回的都是 Promise 对象)
  • response.text():得到文本数据;
  • response.json():得到 JSON 对象(上面例子);
  • response.blob():得到二进制 Blob 对象;
  • response.formData():得到 FormData 表单对象;
  • response.arrayBuffer():得到二进制 ArrayBuffer 对象;

fetch高级用法

请求参数

上面我们有讲过默认情况下fetch是发起get请求,那么如果我们想要发起其他形式的请求(比如post)该怎么做呢?
这就要我们通过fetch第二个参数手动配置fetch的请求方式了,比如我们发起一个post请求并设置请求头,请求体

  • 请求头:
    • Content-Type的默认值是’text/plain;charset=UTF-8’,表示发送的是纯文本;请求的数据体必须为字符串,
    • 'application/json;charset=utf-8’表示发送json数据;此时请求的数据体为json数据,使用JSON.stringify()转化成json字符串
    • "application/x-www-form-urlencoded; charset=UTF-8"表示发送编码格式是’?key=value&key=value’(将键值对的参数用&连接起来,如果有空格,将空格转换为+加号;有特殊符号,将特殊符号转换为ASCII HEX值)此时请求的数据体为提交的表单数据或者文件,要使用new FormData()序列化成键值对
  • fetch默认不带cookie,添加配置项 credentials: 'include’将当前cookie 放在请求中
    -mode表示请求的模式
fetch('http://jsonplaceholder.typicode.com/posts',{
method:'POST',
headers: {
    "Content-type": "application/x-www-form-urlencoded; charset=UTF-8",
},
body: JSON.stringify({'userID':1,'title':'leihou','body':'雷猴'}),
credentials: 'include',
mode: "cors",
})
.then(res => res.json())
.then(data => {console.log(data);})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
Promise结合async/await语法改写,使得语义更清晰
function getList() {
  try {
    let res = await fetch("http://jsonplaceholder.typicode.com/posts");
    let data = res.json();
    console.log(data);
  } catch (error) {
    console.log(error);
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

注意:我们上面提到过fetch()发起请求以后,只有网络错误,或者无法连接时,fetch()才会报错,所以await语句必须放在try…catch里面,才能捕捉异步操作中可能发生的错误;在Promise中await 会暂停执行,等待 Promise 对象 resolve,然后恢复 async 函数的执行并返回解析值;

关于fetch请求的东西暂时先写到这里,此时我已经头昏脑胀了,写不动了…如果以后有需要补充的会继续回来写的。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/148460
推荐阅读
相关标签
  

闽ICP备14008679号