好吧,我有以下代码似乎可以正常运行:
observe(
store, "user",
async (data: {oldValue: ?UserTy, newValue: ?UserTy}) => {
const {oldValue: previousUser, newValue: newUser} = data;
this.entries = [];
this.confirmed_entries = [];
this.paid_entries = [];
if (newUser) {
const clear = !!previousUser;
await this.reloadEntries(clear);
}
this.last_reload = new Date();
}
);
在用户更改(登录/注销)后,哪个将从数据库中重新加载当前用户的“条目”。
现在,我将流量添加到混合中,突然出现以下错误:
错误:(47,64)无法通过绑定到
observe
的异步函数调用listener
,因为返回中的Promise
[1]
与未定义的[2]
不兼容值。
看着mobx.js.flow
,我确实可以看到它总是接受一个简单的函数,返回void
。有关此文件的文档为silent。那么观察者可以在其中接受一个Promise(异步)功能吗? -这是打字中的“错误”吗?
还是我使用观察者是错误的,我只是“幸运”地指出函数最终会执行吗?
如果无法做到这一点,重写它的最佳方法是什么?最后,我需要调用this.reloadEntries()
,它会在更改用户后返回一个Promise /对该服务器进行调用。
答案 0 :(得分:0)
因此,mobx中此observe
函数的侦听器参数的签名为:
listener: (change: IMapChange<K, T>) => void,
相关的位是返回类型void
,它指示该函数应该只能返回undefined
(或者隐含地,由于没有return语句而仅返回undefined
)。
异步函数始终返回Promise
。 the spec中很好地解释了如何执行异步/等待转换以及生成的代码的机制,但足以说明您的代码已被始终返回{{1}的代码有效地替换了}。
最简单的答案是不传递不期望使用的异步函数。以下是一些选项:
Promise
而不是依赖then
。在这种情况下,可能是最干净的选择。await
((...args) => { (async (...) {...})(...args) }
:any
(不要这样做)重新输入函数((myListener): any): (MyArgTypes) => void)
注释(也不要这样做)那么,为什么它起作用?
因为mobx期望一个仅返回$FlowFixMe
的函数,因为它不会对任何返回值执行任何操作。它不要求返回值,因为它不会使用一个。您的返回值void
被mobx丢弃。因此,尽管出现此类型错误,它仍将像往常一样继续工作。
为什么mobx不只是将返回值键入为Promise
?毕竟,mobx不在乎您返回的内容。
因为这将是错误的API设计,并在打字时引入危险的滑移性。 API需要可靠,合理的合同。如果用户由于误解mobx实际上会对该结果做,而让用户传递any
和observe
来返回结果该怎么办?或者,例如,如果用户传递了一个高阶函数而不是那个高阶函数的返回值,该怎么办?在这种情况下,这两种错误都不会被不太严格的类型捕获。
为什么即使我还是要丢弃它,异步函数也总是返回listener
?
虽然仅根据使用情况可以返回Promise
,或者将某种选项传递给不返回Promise
的规范,结果可能是由于很少的回报而使复杂性迅速增加。异步/等待规范的目标是在不增加过多复杂性的情况下获得最大的效用。高度异步的代码库中使用了许多(但不是全部)异步函数,在这些异步代码库中,返回Promise
可能是一个更好的主意。此外,一旦函数被声明为异步,就无法以异步方式(Promise
)安全地从其他函数返回值,而无需以某种方式深入了解函数主体并尝试确定用法。