@minecraft/server-ui的回应是一个Promise
引入
大家都知道Minecraft吗?我认为几乎没有人不熟悉这款神级游戏。我也一直在玩MinecraftBE。
最近我遇到了一个叫做”Gametest Framework”的东西。据说它是为了确认在添加了行为组件包等之后游戏能否正常运行而添加的元素。
然而,实际上它还提供了一些方便的模块,除了确认正常运行之外,也可以用于其他目的。截至目前的1.19.50版本,gametest只能使用javascript编写,可以实现从检测物品使用到重写实体组件等各种不同的功能。
表格是什么
form是GametestFramework提供的模块之一,@minecraft/server-ui模块提供了在Minecraft内使用GUI接收玩家输入的功能。在manifest.json中正确设置dependencies后,将以下脚本写入指定的入口文件中。
import { ActionFormData } from "@minecraft/server-ui";
import { world } from "@minecraft/server";
const form = new ActionFormData()
.title("hoge")
.body("hogehoge")
.button("hogehogehoge");
for(let player of world.getPlayers()) {
form.show(player);
}

承诺是。。。
通过调用form实例的show()方法,可以将其参数指定的玩家显式出来。该方法的返回值是Promise。那么,什么是Promise呢?根据MDN的说法,Promise是一个表示异步操作最终完成或失败的对象。
“Promise(承诺)是一个用于代理到可能在创建时不知道的值的对象。它允许将处理程序与异步操作的成功值或失败原因关联起来。通过返回一个Promise对象来提供未来某时刻的值,而不是同步方法返回结果值,异步方法可以像同步方法一样返回值。”
据说是这样的。不理解含义呢。要是这样的话,就是指在等待玩家输入的同时,程序不会暂停,而是继续执行下去。在这里我遇到了困难。假设有如下代码。
for(let player of world.getPlayers()){
//ここでformの結果を変数に代入している。
const result = form.show(player);
log(result.selection);
我认为理想的行为是“根据玩家输入的表单返回结果”,但是这并没有正常运作。你知道为什么吗?
原因是“在结果被赋值给result之前,log()函数就被执行了”。由于响应类型是Promise的表单,为了提高速度,它会在等待玩家输入的同时并行执行下一步处理。那么我们该怎么做才能得到理想的行为呢?
Promise的并行处理限制
可以通过使用then()来停止Promise的并行处理。
在返回Promise的`form`上调用`.then()`,并在其中使用箭头函数编写希望在`form`输入后执行的操作。例如,
for(let player of world.getPlayers()){
form.show(player).then((result) => {
log(result.selection);
});
}
中文翻译:这种情况下,箭头函数的第一个参数被分配为表单输入信息。需要注意的是,在这种方法中实际上进行了并行处理。如果使用then(),并不意味着不再进行并行处理,而是then()之外的代码会在等待表单输入之前执行。此外,如果按下esc键,点击右上角的关闭按钮,或者关闭表单而没有选择按钮,会将0分配给selection,这可能导致故障。通过检查canceled来排除没有选择任何选项的情况。
最后
由于这是我第一次亲自写的文章,可能会有些难以阅读或难以理解的地方。如果您发现了任何令人困惑的部分,请随时告诉我。
对于编程初学者来说,还有一些陷阱让我自己长时间苦恼不已。我将继续撰写这类问题的解释文章,希望能够拯救更多像“在gametest中进行编程初体验!”那样的人们…。