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

问题描述 投票:1回答:1

好吧,我有以下代码似乎运行良好:

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(异步)函数吗? - 这是打字时的“错误”。 或者我使用观察者是错误的,并且我只是“幸运”该函数最终被执行了吗?

如果一个人不能这样做,那么重写这个的最佳方法是什么?最后,我需要调用qazxsw poi,它会在用户更改时返回一个promise或调用服务器。

javascript asynchronous flowtype mobx
1个回答
0
投票

所以,mobx中这个this.reloadEntries()函数的listener参数的签名是:

observe

相关位是返回类型listener: (change: IMapChange<K, T>) => void, ,它表示该函数应该只能返回void(或者通过没有return语句隐式返回undefined)。

异步函数总是返回undefined。在Promise中很好地解释了如何执行异步/等待转换以及结果代码看起来是什么样的机制,但是可以说你的代码被有效地替换为总会返回the spec的代码。

简短的回答是不要在不期望的情况下传递异步函数。以下是一些选项:

  1. 重做函数只是调用Promise而不是依赖then。在这种情况下可能是最干净的选择。
  2. 将您的异步功能转换为IIFE:await
  3. 通过((...args) => { (async (...) {...})(...args) }any键入来重新输入你的功能(不要这样做)
  4. 使用((myListener): any): (MyArgTypes) => void)评论(不要这样做)

那么,为什么它有用呢?

因为mobx期望一个只返回$FlowFixMe的函数,因为它不会对任何返回值做任何事情。它不会要求返回值,因为它不会使用它。您的返回值,void,只是被mobx丢弃了。因此,尽管存在类型错误,它仍将像往常一样继续工作。

为什么不用mobx只输入返回值为Promise?毕竟,mobx并不关心你的回归。

因为这将是糟糕的API设计并在打字时引入危险的滑溜感。 API需要可靠,合理的合同。如果用户将any传递给返回结果的observe怎么办?因为他们误解了mobx实际上会对该结果做些什么呢?或者,例如,如果用户传递了更高阶函数而不是高阶函数的返回值,该怎么办?在这个位置,这两个错误都不会被不太严格的类型捕获。

为什么异步函数总是返回一个listener,即使我只是要丢弃它呢?

虽然只根据使用情况返回Promise可能已被写入规范,或者可能通过某种选项而不返回Promise,但由于奖励很少,它可能会因复杂性而膨胀。异步/等待规范的目标是在不增加太多复杂性的情况下获得最大可能的效用。许多(但不是全部)异步函数正在高度异步的代码库中使用,其中返回Promise将是一个更好的想法。此外,一旦函数被声明为异步,就无法以异步方式(Promise)安全地返回值,而无需以某种方式挖掘函数体并尝试确定使用情况。

© www.soinside.com 2019 - 2024. All rights reserved.