![](/img/trans.png)
[英]Return data from an asynchronous function into list to be processed later on (remove asynchronous functionality)
[英]Asynchronous functionality in “observe” function
好吧,我有以下似乎运行良好的代码:
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)由于
Promise
[1]
与返回值中的未定义[2]
不兼容,因此无法使用绑定到listener
异步函数调用observe
。
通过查看mobx.js.flow
我确实可以看到它总是接受一个简单的函数,返回void
。 文档对此没有任何说明。 那么观察者可以在其中接受一个Promise(异步)功能吗? -这是打字中的“错误”吗?
还是我使用观察者错误,我只是“幸运地”认为函数最终会执行吗?
如果不能做到这一点,重写它的最佳方法是什么? 最后,我需要调用this.reloadEntries()
,它会在更改用户后返回一个promise /对该服务器进行调用。
因此,mobx中此observe
函数的listener参数的签名为:
listener: (change: IMapChange<K, T>) => void,
相关的位是返回类型void
,它指示该函数应该只能返回undefined
(或者隐含地,只有没有返回语句才能返回undefined
的值)。
异步函数总是返回Promise
。 规范中很好地说明了如何执行异步/等待转换以及生成的代码的机制,但仅说明您的代码已被始终返回Promise
代码有效地替换就足够了。
简短的答案是不传递一个不期望使用的异步函数。 以下是一些选项:
then
依赖于await
。 在这种情况下,可能是最干净的选择。 ((...args) => { (async (...) {...})(...args) }
any
: ((myListener): any): (MyArgTypes) => void)
重新键入函数(不要这样做) $FlowFixMe
注释(也不要这样做) 那么,为什么起作用呢?
因为mobx期望一个仅返回void
的函数,因为它不会对任何返回值执行任何操作。 它不要求返回值,因为它不会使用一个。 您的返回值Promise
只会被mobx丢弃。 因此,尽管存在此类型错误,它仍将像往常一样继续工作。
为什么mobx不只是将返回值键入为any
? 毕竟,mobx不在乎您的回报。
因为这将是不良的API设计,并在键入时带来危险的滑移。 API需要可靠,合理的合同。 如果用户要通过observe
返回一个结果的listener
,因为他们误解了mobx会对结果实际做些什么,该怎么办? 或者,例如,如果用户传递了一个高阶函数而不是那个高阶函数的返回值,该怎么办? 在这种情况下,这两种错误都不会被不太严格的类型捕获。
为什么异步函数总是返回Promise
即使我还是要丢弃它呢?
虽然只返回一个Promise
根据使用情况可能已经被写入规范,或可能通过某种形式的选择不返回的Promise
,这将有可能在复杂性激增的用很少的报酬的结果。 异步/等待规范的目标是在不增加过多复杂性的情况下获得最大的效用。 高度异步的代码库中使用了许多(但不是全部)异步函数,在这些代码库中,返回Promise
可能是个更好的主意。 此外,一旦某个函数被声明为异步,就无法以异步方式( Promise
)安全地从其他方法返回值,而无需以某种方式深入了解函数主体并尝试确定用法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.