請搭配 D10 - 樹狀搜尋問題 實作篇 閱讀。
在實際開發中,我們很少會把資料寫死在程式中,通常都會從檔案、資料庫、或者是第三方服務取得資料。
type getNode = (id:string)=>Promise<Node> // 它可能跑很久、也可能出錯
這就代表我們要處理兩個問題
interface Node {
id: string,
text: string,
childrenIds: readonly string []
}
type getNode = (id:string)=>Promise<Node>
async function getNameById(target:string, rootId: string){
let queue = [rootId]
while(queue.length > 0){
try {
let node = await getNode(queue[0])
if(node.id === target){
return node.text
}
for(let id of node.childrenIds){
queue.push(id)
}
} catch (e) {
console.error(`get id ${queue[0]} failed, skip this node`)
}
queue.shift()
}
return undefined
}
interface Node {
_tag: "Node"
id: string,
text: string,
childrenIds: readonly string []
}
interface NodeNotFoundError {
_tag: "NodeNotFoundError"
id: string,
}
type getNode = (id:string)=>Promise<Node | NodeNotFoundError>
const getNameById = (target:string) => async(id:string):Promise<string|undefined> =>
getNode(id).then((result)=>
result._tag==="Node" && result.id===target ? result.text :
result._tag==="NodeNotFoundError" ? undefined :
Promise.all(result.childrenIds.map(getNameById(target)))
.then(result=>result.find(text=>text!==undefined) )
)
const getNameById = (target:string) => async(id:string):Promise<string|undefined> => {
const result = await getNode(id)
if(result._tag==="NodeNotFoundError") {
console.error(`get id ${id} failed, skip this node`)
return undefined
}
if(result._tag==="Node" && result.text===target) return result.text
const children = await Promise.all(result.childrenIds.map(getNameById(target)))
return children.find(text=>text!==undefined)
}
明天會介紹他們各自有甚麼問題、以及如何解決