大家评评理,去 Deno 提 issue,几位大佬拒不认错

2021-10-11 10:34:22 +08:00
 autoxbc
讨论串在这里
https://github.com/denoland/deno/issues/12298

核心问题是,从本地文件创建的 Uint8Array 和其对应的 ArrayBuffer 不一致(buffer 结尾多了一个字符),大佬非说这也正常,让我自己改调用方式去 workaround

我本来支持的 issue 发起者已经认怂了,我不服气
5389 次点击
所在节点    JavaScript
11 条回复
oott123
2021-10-11 10:41:17 +08:00
Uint8Array 是 ArrayBuffer 的一个 view,你要读底下的 buffer 的话,还得看 byteOffset 和 length 这两个属性。

这确实只能说行为变了,而不能说是 bug 。虽然很多大型项目这种行为变化也会慎重考虑甚至写进 changelog,但对于 deno 这种<del>玩票性质</del>严格遵守最佳实践的项目文档里没有的东西当然是说变就变了。
autoxbc
2021-10-11 10:52:41 +08:00
@oott123 #1 这是一个基于 ArrayBuffer 全量构造的 Uint8Array,不存在 byteOffset 和 length 的问题,两者长度严格相等是很自然的要求
oott123
2021-10-11 10:56:55 +08:00
@autoxbc 我手头没有 deno 环境,如果能把 byteOffset 和 length 两个属性打出来看看就好了。至于是不是“基于 ArrayBuffer 全量构造的 Uint8Array”的,我想文档里应该没有定义它是,所以是和不是都合法。
libook
2021-10-11 12:22:40 +08:00
当前其实有 3 个问题杂糅在一起了,第一个问题是 Uint8Array 和 ArrayBuffer 是不是“1-to-1 match”的:

去查了查 ES 规范,不知道是否有参考价值:
https://262.ecma-international.org/6.0/#sec-uint8array
用 TypedArray 通用规范来描述的:
https://262.ecma-international.org/6.0/#sec-typedarray-constructors
然后看用什么方法转换格式:
https://262.ecma-international.org/6.0/#table-49
用的是 ToUint8 方法进行的转换:
https://262.ecma-international.org/6.0/#sec-touint8
到这里就能看到,数据不是完全映射过去的。

个人认为 maintainer 对于“not that they're a 1-to-1 match”的观点是对的。

另一个问题是这个算不算是 breaking change:
如果出问题的用法是规范明确提到的常规用法的话,那么这个确实算是 breaking change,在 changelog 里应当提到。

第三个问题是 Deno 的相关 API 返回什么数据类型是合理的,这个就有太多主观因素了。

这些我都没怎么用过,只是花了几分钟去探究了一下,要是说得不对请指正。
说实话,Deno 推广的时候用了太多歪门邪道,导致我对它的印象一直都不大好。
mxT52CRuqR6o5
2021-10-11 12:48:36 +08:00
```
const input = document.createElement("input");
input.type = "file";
input.addEventListener("change", async (event) => {
const arrayBuffer = await input!.files![0].arrayBuffer();
const uint8Array = new Uint8Array(arrayBuffer).subarray(0, 1);
console.log(uint8Array.byteLength);
console.log(uint8Array.buffer.byteLength);
});
document.body.append(input);
```
在 chrome 上试了一下,一个 uint8Array 实例的 byteLength 和它的 buffer.byteLength 不一样是可以达到的,那就没有不合 js 规范的问题,单纯的是 Deno.readFileSync 表现的问题
Mohanson
2021-10-11 13:33:13 +08:00
不算难以理解, ArrayBuffer 毕竟是 Buffer, 不能对这个底层实现的 Buffer 有先验知识. 这种问题最好加一下 changelog 但个人不认为是 bug.
autoxbc
2021-10-11 16:09:05 +08:00
@libook #4 我并不介意 breaking change,Deno 这类变动很多次了。只是这次摆出我定义这是一个 feature 他就不是一个 bug 不对劲
autoxbc
2021-10-11 16:15:47 +08:00
@mxT52CRuqR6o5 #5 长度不一致是正常的,但前提是构造的时候切过了,这全量构造是不一样的
mxT52CRuqR6o5
2021-10-11 16:21:06 +08:00
@autoxbc
你 Deno.readFileSync 就已经拿到的是 uint8array 了,切还是全量构造是 Deno.readFileSync 内部的事情,为什么你认为 Deno.readFileSync 一定要给你全量构造的 uint8array
现在作者明显就是想要 Deno.readFileSync 返回切过的 uint8array 这个效果,那肯定说这是个 feature 啊
iugo
2022-02-23 15:29:05 +08:00
不知道我看到的情况和当时有多大差别, 但主要维护者还是对这样的修改有讨论的: https://github.com/denoland/deno/pull/12057#pullrequestreview-753151404

还是一个 API 设计问题吧, 可以讨论.
autoxbc
2022-02-24 00:14:09 +08:00
@iugo #10 谢谢,原来是为了优化读取性能。不过也只是微小的提升,就搞了个丑设计,感觉得不偿失

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/806967

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX