Skip to content
This repository has been archived by the owner on Aug 15, 2023. It is now read-only.

如果 fetch 工作了很久,那么或许整个页面加载完数据都不会被读入 #329

Closed
Arondight opened this issue Oct 31, 2021 · 21 comments
Assignees
Labels
bug Something isn't working

Comments

@Arondight
Copy link
Owner

归根结底, fetch 是一个异步方法,既然有了一个异步方法,那么就永远无法保证其顺序,如果 fetch 工作了很久,那么或许整个页面加载完数据都不会被读入

Originally posted by @Arondight in #328 (reply in thread)

@Arondight Arondight added the question Further information is requested label Oct 31, 2021
@Arondight
Copy link
Owner Author

下面的数据在 computed 中不能保证是已经读取完成的,目前读一个文件出问题的概率很低,多加一个文件就会大概率出现数据 undefined 。

methods: {
readJSON(file, callback) {
fetch(file).then((res) => {
return res.json().then((data) => {
callback(data);
});
});
},
},
mounted() {
this.readJSON("../../data/record/genshin-artifact.json", (res) => {
this.base = res.base;
this.data = res.data;
this.mainStat = res.mainStat;
});
},

@Arondight
Copy link
Owner Author

我在想这个问题有可能是无法解决的,因为 vue 的 hook 有可能就不能保证顺序执行,看样子好像是某个阶段启动某个 hook ,没说会等上一阶段的执行完毕

@Arondight
Copy link
Owner Author

这个问题有可能是无法解决的

我在想是不是这个项目的使用方式有问题,我感觉我得学学 vue 🤨

@mark9804
Copy link
Collaborator

这个项目的vue的部分确实挺不成熟的,感觉我们几个人里面最能写的是 @490720818 这个老大哥

@Arondight
Copy link
Owner Author

我泠帮忙看看这问题咋处理呀 @impasse

@Arondight
Copy link
Owner Author

问了几个老大哥,似乎 vue 在 v-bind 读到数据后(无论是不是 undefined ),当 mounted 中函数工作完成后,v-bind 会再次读入数据。

但是当前 fetch 是异步的,所以函数执行完毕时数据读取极大概率尚未完成,再次刷新时可能仍然会读到 undefined (或者其他初始化的数据而非 json 中的数据)

@Arondight Arondight mentioned this issue Nov 2, 2021
7 tasks
@Arondight
Copy link
Owner Author

@mark9804 @490720818 我注意到 @SilveryStar 可能为了避免这个问题,不再使用文件给浏览器传递数据,而是直接把数据写到了 url 的参数中,我感觉我们也可以学的这么做。

https://github.com/SilveryStar/Adachi-BOT/blob/aeebf063a5234bf74bc345cbe425f9d502444abb/src/plugins/genshin/utils/render.ts#L40

@mark9804
Copy link
Collaborator

mark9804 commented Nov 4, 2021

url最长有2048字符数的限制,能塞得下就行 IE已经断气了,我觉得应该可行

不过假设我们总是有一个氪佬用户氪了全图鉴,那米游社的参数之后会越来越长……

@Arondight
Copy link
Owner Author

@mark9804 就是说现代浏览器支持超长 url 吗

@mark9804
Copy link
Collaborator

mark9804 commented Nov 4, 2021

@mark9804 就是说现代浏览器支持超长 url 吗

理论上是这样,不过Chrome具体能多长我没测试过,或者也有可能现在用的server不支持这么长的url,当前项目用的什么server我还没看过。

超长url是一个木桶,对长url支持最差的一个节点决定这个url能多长。比如chrome支持上万字符,当前的localhost只支持到2048字符还是一样不行的,会返回414 too long

@Arondight
Copy link
Owner Author

@mark9804 node 本身应该不会出现问题,因为他们添加了参数 --max-http-header-size ,我想即使没有参数默认 8 * 1024 8KiB 也是够用的

@Arondight
Copy link
Owner Author

我想下周就做这件事情,现在使用缓存的逻辑本来就很奇怪,这件事情一下解决了两个问题。

@Arondight Arondight added bug Something isn't working and removed question Further information is requested labels Nov 4, 2021
@Arondight Arondight self-assigned this Nov 4, 2021
@Arondight
Copy link
Owner Author

现在使用缓存的逻辑本来就很奇怪,这件事情一下解决了两个问题

肝了一天,现在代码终于正常一点了,只需把这个缓存逻辑改的正常一点,这个项目就终于有望看上去正常一些了。

@Arondight
Copy link
Owner Author

@mark9804 你知道通过 url 数据后中文乱码是为啥么

图片

浏览器看也是乱码

图片

@Arondight
Copy link
Owner Author

Arondight commented Nov 13, 2021

后端: object1 -> string -> base64 -> object2 -> string(params)
前端: object2 -> base64d -> string -> object1

@mark9804
Copy link
Collaborator

经典前端问题,charset不一样,但是我已经指定了编码是UTF-8了呀,那很大可能传过来的数据编码不是utf-8

<meta charset="UTF-8" />

@Arondight
Copy link
Owner Author

经典前端问题

查了下是浏览器的 atob 函数不支持 utf ,我看看咋搞

@mark9804
Copy link
Collaborator

简单粗暴的解决方法是:只要知道传过去的是什么编码,我们在前端声明编码格式就可以了

这个meta标签如果要写完整的话是

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

其中charset可以是gbk,也可以是其他什么编码

@Arondight
Copy link
Owner Author

图片

啊这,我搞定了

@mark9804
Copy link
Collaborator

啊这,我搞定了

牛皮

@Arondight
Copy link
Owner Author

@mark9804 因为现在所有的数据都通过 URL 传入,你原来的方法调试起来是有困难的,所以配置文件增加了参数 viewDebug ,调试的时候设置为 1 即可。

#
# 前端调试模式,不再使用浏览器的无头模式,并且不再关闭标签页
# 1:使用调试模式、 0:不使用调试模式
#
viewDebug: 0

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants