用fetch 读取文本

2,303 阅读2分钟

「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战

最近好像有不少文章在写axios,但是我却对fetch更青睐。因为在不依靠外部库的情况下,也就是xhr和fetch了。

但是, xhr的写法略微有些麻烦,我基本上忘了。fetch也不熟。不过,fecth直接返回promise,所以,可以直接用promise的方法。

我只是想在写webgl时,把着色器单独放在一个文件里,然后用js去读。 因为 script标签的语法提示还是不够友好啊,我只是个菜鸟,需要友好的语法提示来纠正我的低级错误。

前端没有直接通过文件路径读取文件的方法,只能通过请求了。

我本来就是写个简单的demo,读个文本文件而已,所以不想引入额外的库。 于是就想试试fecth.我本以为,fetch 只要调用就能直接读取文件字符串,没想到,它是这样的fetch。

 let vs = await fetch('./shader.vert')
    console.log(vs)

结果并不是我想的字符串或者一个简单的对象,果然,还是用库用多了。

image.png

Response

fetch确实返回Promise,所以可以直接用await, 但是似乎并没有直接把结果给我, 而是来了这么一个response对象。并且咋一看,似乎没有我想要的文本,在没有处理之前,请求的返回值都是文本,这是我之前的常识。

然而fetch给我上了一课,在没有处理之前,响应结果连文本都不是,而是接近原始的二进制数据流。

看看response的属性,就能猜出,我们想要的结果就在body里,但是点开body,只能看到一个 ReadableStream。

ReadableStream

字面意思,可读流。

不过fecth的body实现了更为具体的流,

ArrayBuffer
ArrayBufferView
Blob
string
......

我这里显然是string,所以只要调用text()方法就可以拿到一个string类型的结果了。

然而事情斌还没有这么简单,这个text()方法返回的是一个Promise ,所以还得来上一层才行呢。

因此我的最终代码就是

    let vs = await (await fetch('./shader.vert')).text()
    let fs = await (await fetch('./shader.frag')).text()
    console.log(vs,fs)

image.png

结果就是我想要的。 不过注意await只能用在 async 修饰了的函数里,别忘了。