需求分析:根據一級標題ID篩選出所有對應的二級標題,返回一級標題ID,標題名和二級標題ID,標題名組成的數組
問題:通過forEach遍歷所有一級標題取對應的ID,根據ID條件查找所有的二級標題,遍歷符合條件的二級,取出二級標題的ID和標題名,此時,循環內部嵌套條件查找是個異步函數,resolve返回的結果為空。注:此處getSecondTitle為封裝的讀取數據庫的異步函數
const allTitleId =function(firstTitleArray){return new Promise(function(resolve,reject){let secondArr=[],secondObj={},itemObj={},dataArray=[];//console.log(1)firstTitleArray.forEach(function(item){console.log(1)getSecondTitle(item).then(function(ret){// console.log(ret)secondArr=[];ret.forEach((item2)=>{secondObj={};secondObj['_id'] = String(item2._id);secondObj['title'] = item2.title;secondArr.push(secondObj)//console.log(secondArr) })console.log(2)itemObj = JSON.parse(JSON.stringify(item));itemObj['secondTitle']= secondArr;dataArray.push(itemObj)}).catch(function(err){reject(err)})})console.log(3)resolve(dataArray)}) }
解決:javascript代碼都是同步執行的,代碼都在在一個代碼“隊列”里面。與此同時javascript還有一個“Event Queue”,事件隊列里都是處理一些異步的callback/handler,處理ajax response,點擊啊,文件,數據庫操作結果。關鍵是,只有代碼隊列所有代碼都執行完畢了,javascript才會從事件隊列里取出一個callback/handler來執行。依賴于事件循環處理異步函數獲取數據,會導致腳本事件執行順序不正確,無法按需求獲取數據。應采用遞歸方法處理異步函數獲取數據。
const allTitleId =function(firstTitleArray){return new Promise(function(resolve,reject){let secondArr=[],secondObj={},itemObj={},dataArray=[];(function secondTitleloop(index){getSecondTitle(firstTitleArray[index]).then(function(ret){secondArr=[];ret.forEach((item2)=>{secondObj={};secondObj['_id'] = String(item2._id);secondObj['title'] = item2.title;secondArr.push(secondObj)})itemObj = JSON.parse(JSON.stringify(firstTitleArray[index]));itemObj['secondTitle']= secondArr;dataArray.push(itemObj)if (++index<firstTitleArray.length) {secondTitleloop(index);} else {resolve(dataArray)}}).catch(function(err){reject(err)})})(0)}) }
?