這是公司一位小朋友的代碼,他很疑惑為什么info是undefined;
let list = [
{
type: 5,
name: '創(chuàng)建節(jié)點',
ondid: 'd8b30f2e',
flowNodeType: 'node',
propObj: { bgType: 5, topName: '創(chuàng)建節(jié)點', contentName: '申請人', flag: -1, list: [] },
},
{
ondid: 'f97f3da8',
flowNodeType: 'branchbox',
list: [
{ flowNodeType: 'branch', ondid: '71edab98', propObj: { list: [] } },
{ flowNodeType: 'branch', ondid: '5936d6f4', propObj: { list: [] } },
],
},
];
let obj = {
flowNodeType: 'branch',
ondid: '5936d6f4',
};
let obj = {
flowNodeType: 'branch',
ondid: 'tmp-5936d6f4-ddfb-4254-8902-69198e10f8db-branch',
};
async function getIndex(ondid, list) {
let index = list.findIndex((item) => item.ondid == ondid);
return index;
}
/**
* 分支消息
* @param {*} obj
* @param {*} list
*/
async function getBranchInfo(obj, list) {
let index = getIndex(obj.ondid, list);
if (index >= 0) {
return list[index];
}
list.forEach((item) => {
if (item.flowNodeType == 'branchbox') {
item.list.forEach((row) => {
getBranchInfo(obj, item.list);
});
} else if (item.flowNodeType == 'branch') {
item.propObj.list.forEach((item) => {
getBranchInfo(obj, item.propObj.list);
});
}
});
}
// 遞歸循環(huán)獲取對象數(shù)據(jù) 先獲取 { { { a=1} } }
async function serachInfo(obj, list) {
if (obj.flowNodeType == 'node') {
// ...
} else if (obj.flowNodeType == 'branch') {
let info = await getBranchInfo(obj, list);
console.log(info); // ??? 為什么是undefined
}
}
serachInfo(obj, list);
首先這段代碼里有幾個明顯的問題?
1、forEach中使用return是無效的。
2、還有一個問題,async function xxx 的返回值是promise,需要用await來接收,并且都是同步代碼,不需要用async/await來包裹。
3、getBranchInfo函數(shù)職責不單一
改造意見:
1、getBranchInfo職責單一化,可以將查找list的邏輯抽離到searchInfo中,getBranchInfo只用來判斷當前傳入的list是否含有符合條件的節(jié)點。
2、findIndex獲取index,然后又從list[index]獲取節(jié)點,其實也不必這么麻煩,可以用Array.find實現(xiàn),不用這么麻煩,第一個就可以直接忽略了
3、searchInfo中,利用方式廣度優(yōu)先的策略,將list的所有子list合并成一個數(shù)組,作為參數(shù),遞歸傳入searchInfo中,遞歸結(jié)束條件:調(diào)用getBranchInfo獲取到符合條件的節(jié)點。
改造以后的代碼
function searchInfo (obj, list) {
let info = list.find(item => {
return item.ondid === obj.ondid
})
if (info) {
return info
}
let nextLevel = []
for (let item of list) {
if (item.flowNodeType === 'node') {
nextLevel = nextLevel.concat(item.propObj.list)
} else {
nextLevel = nextLevel.concat(item.list)
}
}
return searchInfo(obj, nextLevel)
}
console.log(searchInfo(obj, list))