繁体   English   中英

“观察”功能中的异步功能

[英]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代码有效地替换就足够了。

简短的答案是不传递一个不期望使用的异步函数。 以下是一些选项:

  1. 重做该函数以仅调用then依赖于await 在这种情况下,可能是最干净的选择。
  2. 将您的异步函数转换为IIFE: ((...args) => { (async (...) {...})(...args) }
  3. 通过键入any((myListener): any): (MyArgTypes) => void)重新键入函数(不要这样做)
  4. 使用$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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM