2017-11-17 173 views
2

我正在将流程添加到项目,并且遇到了一个我找不到的错误。下面是一些产生相同的错误代码:处理多个承诺和回调时混淆流程错误

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'); 
    } 

我一直无法找出任何方式来获得流量,接受此代码,在不改变的东西,我不能真正改变(就像一个简单的返回更换数据库的代码)。

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

回答

1

thing函数的返回类型明确设置为Promise<user>,这就是为什么你的错误,因为你callback传递参数{}这不是user

我不知道您的具体要求是什么为什么您使用的是timeout但如果返回类型可以是东西是不是user,这意味着any可以使返回类型:您可以将返回类型Promise<user|any>

You explicitly set the return type, so you have to return that return type.

+0

不加入'| any'基本上就放弃了?如果我尝试'|错误'和一些改进,同样的问题。 [例子链接](https://flow.org/try/#0C4TwDgpgBArgzhATlAvFA3gKClAlgEwC4o5hFcA7AcwBpMBfAbk0wGMB7C0qYAC0qqooAMxgVWwXJwAUASmIAFROwC2uBAB54SKAB8RAQwA2CAHwZsURBGAxEFKBQgB3KEtXqI063HZGAbtAo5lg4OP4GyGAAjEJOru5qCNKUTogAShC+AUEhlmFQVDYAIgbABtL4ZQaoeTgAkPW4wlDSoJDsLVXlqChoAOTsAEYAVhAS-VAAZFM84BCdUN0GAHQEvQOk5NT9shYFB3gUaZnZgZXVssyHOPRQECbQoTc4qUinfufCxgiy+Qf0f63K7-egggqJTwrYxGaQAbRiAF1ZCs+BAKN4sjAjMBavsDj5Pl4fNjgHCAAzI65hMHU2kMZhsTjcIrAUo9NCicSSGSsGFDAysADWe2eCGAABVcCoFjBgNI5Hjnjg+UYjALhdJ0PTbjQoNFyYaQUwgA) – fnsjdnfksjdb

+0

若你明确了解并知道肯定不同的数据类型将是通过。为什么不把像{{id:“someID”}'这样的用户传递给你的回调? 'callback({id:“someID”});'你说你的'getData'将适合来自API的数据,那么问题在哪里? –

+0

我的意思是'getData'函数只是一个占位符。它通常应该与用户进行响应,但实际上访问数据库时有可能会返回其他内容。我确实解释了我可以期望的主要类型的回应。 – fnsjdnfksjdb

0

的确,空对象不是user类型。当你不匹配时返回一个空对象,而不是返回一个空数组,并使你的函数返回一个数组。

这改变了语义:thing在没有匹配的情况下返回一个空数组的承诺,或者当有数组时有一个元素的数组。

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

...而回拨电话应传递一个数组具有零个或一个元素:

callback([]); 

示例代码也可以减少到这一点,但我假设你有一个由其他代码,然后把它写像你这样:

type user = { 
    id: string, 
}; 

const thing = function(): Promise<user[]> { 
    return new Promise(getData); 
}; 

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

Try Flow

+0

我无法更改getData返回的内容 - 它代表访问数据库的函数。当我尝试复制你所做的,但通过检测非用户对象并在回调中返回一个空数组时,它不起作用。 – fnsjdnfksjdb