async/await与resolve()使用问题:查询完成后soapMessageJson为空的解决方法咨询
async/await与resolve()使用问题:查询完成后soapMessageJson为空的解决方法咨询
兄弟我太懂你这种被异步回调绕得头大的痛苦了😂,你遇到的问题核心就是异步操作没等它做完就急着用结果,导致soapMessageJson还没被塞数据,就跑去执行sendSoapMessage()了,自然是空数组。
咱先拆解下问题根因:你现在的parseAndSaveCti是个普通同步函数,但里面处理CSV解析、数据库查询这些操作肯定都是异步的(比如读文件、查数据库不会瞬间完成)。你在同步函数里定义了soapMessageJson,然后在异步回调里往里面塞数据,但函数本身早就执行完了——等异步操作真的把数据塞进去的时候,sendSoapMessage()早就跑完了,当然拿不到东西。
给你几个具体的解决步骤,结合你的代码改就行:
1. 先把函数改成async类型
只有把parseAndSaveCti声明成async函数,里面才能用await等待异步操作完成,不然所有异步代码都会“飞”在同步代码后面。
2. 把所有异步操作用await或者Promise包裹,确保顺序执行
比如你解析CSV的代码,大概率是用了流或者回调,得把它包成Promise,然后用await等它完全解析完,再处理数据。
3. 把sendSoapMessage()放在所有异步操作完成后调用
绝对不能在函数外面或者异步操作还没结束的时候调用它,必须等soapMessageJson被完全填充后再执行。
给你改好的代码示例,贴合你原来的逻辑:
// 把函数改成async,支持await async function parseAndSaveCti(product) { const latestFile = getLatestFile(ctiDir, product.fileType); if (!latestFile) { console.log('CTI: CSV 파일을 찾을 수 없습니다.'); return []; // 返回空数组避免后续报错 } if(product.lastProcessedFile === latestFile){ console.log(`CTI ${product.name} 파싱 오류: 새로운 파일이 없습니다. 파싱을 종료합니다.`); return []; } // 这里注意!你原来写的是ctiController.lastProcessedFile,是不是应该是product.lastProcessedFile?小bug提一嘴 product.lastProcessedFile = latestFile; const latestFilePath = path.join(ctiDir, latestFile); console.log(`최신 파일에서 데이터를 파싱 및 저장: ${latestFilePath}`); let soapMessageJson = []; // 把CSV解析的异步操作包成Promise,用await等它完成 await new Promise((resolve, reject) => { // 假设你用的是常见的csv-parser库,流解析CSV fs.createReadStream(latestFilePath) .pipe(csv()) .on('data', (row) => { // 每一行解析完就塞进数组 soapMessageJson.push(row); }) .on('end', () => { console.log('CSV 파싱 완료,所有数据已存入soapMessageJson'); resolve(); // 这里才resolve,确保数据都塞完了 }) .on('error', (err) => { console.error('CSV 파싱 오류:', err); reject(err); }); }); // 如果你还有数据库查询的异步操作,也要用await等它 // 比如:const dbData = await yourDbQuery(); soapMessageJson.push(...dbData); // 现在所有数据都准备好了,再调用sendSoapMessage sendSoapMessage(soapMessageJson); // 也可以把数组返回,方便外部用 return soapMessageJson; } // 调用这个函数的时候也要用await,不然还是会不等它做完就继续 async function runProcess() { await parseAndSaveCti(yourProductData); } runProcess();
额外提醒
- 别在同步函数里混异步代码,要么全用Promise链,要么用async/await,别来回跳
- 检查你原来的
ctiController.lastProcessedFile = latestFile;是不是应该赋值给product.lastProcessedFile?你前面判断的是product.lastProcessedFile === latestFile,这里赋值给了ctiController,可能是个小疏漏,虽然和当前问题无关,但容易导致后续逻辑出错
备注:内容来源于stack exchange,提问作者Chihyun Ahn
相关产品推荐
相关产品推荐

