2017-11-17 176 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