iT邦幫忙

2024 iThome 鐵人賽

DAY 13
0
Software Development

六邊形戰士程式設計系列 第 13

D13 - 樹狀搜尋問題 非同步版 實作篇

  • 分享至 

  • xImage
  •  

請搭配 D10 - 樹狀搜尋問題 實作篇 閱讀。

在實際開發中,我們很少會把資料寫死在程式中,通常都會從檔案、資料庫、或者是第三方服務取得資料。

type getNode = (id:string)=>Promise<Node> // 它可能跑很久、也可能出錯

這就代表我們要處理兩個問題

  1. 取得外部資料需要時間,沒處理好可能造成效能問題
  2. 取得外部資料可能出錯,沒處理到的話程式會炸掉、沒處理好會很難偵錯與修復

結構化程式設計

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

明天會介紹他們各自有甚麼問題、以及如何解決


上一篇
D12 - 樹狀搜尋問題 效能分析篇
下一篇
D14 - 樹狀搜尋問題 非同步版 說明篇
系列文
六邊形戰士程式設計30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言