处理多个承诺和回调时混淆流错误

时间:2017-11-17 21:35:48

标签: javascript es6-promise flowtype

我正在为项目添加流量,而且我遇到了一个我无法弄清楚的错误。这里有一些产生相同错误的代码:

type user = {
  id: string,
};

const thing = function(): Promise<user> {
  return new Promise(resolve => {
    var p1 = new Promise(innerResolve => {
      getData(data => {
        innerResolve(data);
      });
    });
    Promise.all([p1]).then(result => {
      resolve(result[0]);
    });
  });
};

const getData = function(callback) {
  setTimeout(() => {
    callback({});
  }, 1000);
};

Link to this code on Try Flow, where you can read the error.

在我的应用程序中,getData函数转到数据库以获取对象。它在回调中返回的类型只能是这个特定的:

{
  [key: string]: string,
}

因此可以使用空对象调用它,就像在示例中一样。如果用以下代码替换该行:

callback({id: 'working'})

没有类型错误。但我不能在我的申请表中这样做。

另一件奇怪的事情是我可以删除整个块:

Promise.all([p1]).then(result => {
  resolve(result[0]);
});

这也使它通过了流量测试。

我认为有一点可以解决这个问题 - 改进 - 不能解决问题。

    if (typeof data === 'object' && typeof data.id === 'string') {
      innerResolve(data);
    } else {
      throw new Error('bad db response');
    }

我还没有找到任何方法让流程接受这段代码,而不会改变我能够实际改变的东西(比如用简单的回报替换数据库代码)。

任何人都可以解释我看到的错误,以及为什么我会触发错误吗?

2 个答案:

答案 0 :(得分:1)

您明确将thing函数的返回类型设置为Promise<user>,这就是您callback传递参数{}后错误的原因user

我不知道您的具体要求是什么或为什么使用timeout,但如果返回类型 可能是user,则意味着{ {1}}您可以创建返回类型:您可以将返回类型设置为any

  

您显式设置了返回类型,因此您必须返回该返回类型。

答案 1 :(得分:0)

实际上,空对象的类型不是Pyro.errors。当你没有匹配时,不是返回一个空对象,而是返回一个空数组,并让你的user函数返回一个数组。

这改变了语义:thing在没有匹配时返回空数组的promise,或者在有数据时返回包含一个元素的数组。

thing

...并且回调调用应该传递一个包含零个或一个元素的数组:

const thing = function(): Promise<user[]> {

您的示例代码也可以简化为此,但我认为您还有其他代码可以像您一样编写代码:

callback([]);

Try Flow