JavaScript中独立for循环意外重复执行问题求助
循环执行次数不符合预期排查
问题描述
获取API响应后,用for循环遍历响应并做多条件判断;之后写了独立的第二个循环放在wholeUpdate函数里,原本想避免重复操作,但第二个循环的执行次数和第一个循环(遍历3条数据)相同。传入wholeUpdate的filteredArr应该只包含1条去重后的数据,理论上第二个循环仅执行1次,实际却执行了3次。
相关代码
async function doGetRequest() { var filteredArr = []; var unique = []; var cosmos = [{ "_id": "63773144c3160f782c087e35", "nfrid": "637328ebf5c4b2558b064809", "nfrname": "azuread", "fileName": "index.js", "isImport": true, "isConst": false, "isComponent": false, "isNewFile": false, "isPackage": false, "landmark": null, "isAfter": null, "fileContent": "import { MsalProvider } from '@azure/msal-react';import { msalConfig } from './authConfig';import {PublicClientApplication } from '@azure/msal-browser';", "filePath": "src/index.js", "isIndexHtml": false, "projecttypeid": "6372366d1b568e00d8af2e44", "projecttypetitle": "PWA React", "isReplace": false, "nfrGitIo": [{ "_id": "637328ebf5c4b2558b064809", "iconpath": "https://cdnerapidxdevportal.azureedge.net/webdesignerimages/azure-active-directory-aad-icon-488x512-3d71nrtk.png", "title": "Azure AD", "description": "Azure Active Directory (Azure AD), part of Microsoft Entra, is an enterprise identity service that provides single sign-on, multifactor authentication, and conditional access to guard against 99.9 percent of cybersecurity attacks." }] }, { "_id": "63773195c3160f782c087e36", "nfrid": "637328ebf5c4b2558b064809", "nfrname": "azuread", "fileName": "index.js", "isImport": false, "isConst": true, "isComponent": false, "isNewFile": false, "isPackage": false, "landmark": `("root"));`, "isAfter": true, "fileContent": "const msalInstance = new PublicClientApplication(msalConfig);", "filePath": "src/index.js", "isIndexHtml": false, "projecttypeid": "6372366d1b568e00d8af2e44", "projecttypetitle": "PWA React", "isReplace": false, "nfrGitIo": [{ "_id": "637328ebf5c4b2558b064809", "iconpath": "https://cdnerapidxdevportal.azureedge.net/webdesignerimages/azure-active-directory-aad-icon-488x512-3d71nrtk.png", "title": "Azure AD", "description": "Azure Active Directory (Azure AD), part of Microsoft Entra, is an enterprise identity service that provides single sign-on, multifactor authentication, and conditional access to guard against 99.9 percent of cybersecurity attacks." }] }, { "_id": "637731a2c3160f782c087e37", "nfrid": "637328ebf5c4b2558b064809", "nfrname": "azuread", "fileName": "index.js", "isImport": false, "isConst": false, "isComponent": true, "isNewFile": false, "isPackage": false, "landmark": "<App />", "isAfter": null, "fileContent": "<MsalProvider instance={msalInstance}><App /></MsalProvider>", "filePath": "src/index.js", "isIndexHtml": false, "projecttypeid": "6372366d1b568e00d8af2e44", "projecttypetitle": "PWA React", "isReplace": true, "nfrGitIo": [{ "_id": "637328ebf5c4b2558b064809", "iconpath": "https://cdnerapidxdevportal.azureedge.net/webdesignerimages/azure-active-directory-aad-icon-488x512-3d71nrtk.png", "title": "Azure AD", "description": "Azure Active Directory (Azure AD), part of Microsoft Entra, is an enterprise identity service that provides single sign-on, multifactor authentication, and conditional access to guard against 99.9 percent of cybersecurity attacks." }] } ]; unique = cosmos.map(item => item.fileName).filter((value, index, self) => self.indexOf(value) === index); console.log(unique); const seen = new Set(); filteredArr = cosmos.filter(el => { const duplicate = seen.has(el.fileName); seen.add(el.fileName); return !duplicate; }); try { for (let index = 0; index < cosmos.length; index++) { for (let i = 0; i < unique.length; i++) { if (cosmos[index].fileName === unique[i]) { if (cosmos[index].isPackage === true) { var statusPackage = "import"; console.log(statusPackage); } else if (cosmos[index].isImport === true) { var statusImport = "pack" console.log(statusImport); } else if (cosmos[index].isConst === true) { var statusConst = "third"; console.log(statusConst); } else if (cosmos[index].isComponent === true) { var statusComponent = "okay" console.log(statusComponent); } else if (cosmos[index].isNewFile === true) { var statusNewFile = "okyy"; console.log(statusNewFile); } else if (cosmos[index].isIndexHtml === true) { var statusIndexHtml = "kk"; console.log(statusIndexHtml); } } } } } finally { wholeUpdate(filteredArr); } } function wholeUpdate(filteredArr) { for (let index = 0; index < filteredArr.length; index++) { var status = common.updateFullContent(filteredArr[index]); console.log(status); } } doGetRequest();
排查步骤与解决方案
确认filteredArr的实际长度
你的filteredArr生成逻辑是正确的,3条数据的fileName都是index.js,去重后应该只有1条数据。可以在调用wholeUpdate前打印数组长度,确认是否符合预期:finally { console.log('传入wholeUpdate的数组长度:', filteredArr.length); wholeUpdate(filteredArr); }区分循环次数与内部函数的输出
你看到的3次输出可能不是wholeUpdate里的循环执行了3次,而是common.updateFullContent函数内部有循环或多次打印。可以在wholeUpdate的循环里添加索引打印,明确循环执行次数:function wholeUpdate(filteredArr) { console.log('wholeUpdate循环总次数:', filteredArr.length); for (let index = 0; index < filteredArr.length; index++) { console.log('当前循环索引:', index); var status = common.updateFullContent(filteredArr[index]); console.log(status); } }防止数组被意外修改
用const声明filteredArr,避免后续代码意外修改这个数组的长度:const seen = new Set(); const filteredArr = cosmos.filter(el => { const duplicate = seen.has(el.fileName); seen.add(el.fileName); return !duplicate; });优化第一个嵌套循环
你第一个循环里的嵌套判断完全没必要,因为每个cosmos元素的fileName必然在unique数组里,直接遍历cosmos处理即可:try { for (const item of cosmos) { if (item.isPackage) { console.log("import"); } else if (item.isImport) { console.log("pack"); } else if (item.isConst) { console.log("third"); } else if (item.isComponent) { console.log("okay"); } else if (item.isNewFile) { console.log("okyy"); } else if (item.isIndexHtml) { console.log("kk"); } } } finally { wholeUpdate(filteredArr); }
内容的提问来源于stack exchange,提问作者user19672461
相关产品推荐
相关产品推荐

