如何使用async、await和resolve()

问题描述 投票:0回答:1

我正在尝试执行查询并获取结果,当查询全部完成后,执行“sendSoapMessage(soapMessageJson)”。但是我发现每次运行这个程序时,soapMessageJson 都是空的。肯定和async、await、resolve()的使用有关;关于如何解决这个问题有什么想法吗?我对使用这个异步函数感到很困惑。 TT

这是代码。 (节点.js)

// CSV 파일을 파싱하고 데이터베이스에 저장하는 함수
function parseAndSaveCti(product) {
  const latestFile = getLatestFile(ctiDir, product.fileType); // 가장 최신의 CSV 파일을 찾음
  if (!latestFile) { // 파일이 없는 경우
    console.log('CTI: CSV 파일을 찾을 수 없습니다.');
    return;
  }

  if(product.lastProcessedFile === latestFile){
    console.log(`CTI ${product.name} 파싱 오류: 새로운 파일이 없습니다. 파싱을 종료합니다.`);
    return;
  }

  ctiController.lastProcessedFile = latestFile;

  const latestFilePath = path.join(ctiDir, latestFile); // 최신 파일의 경로를 구성
  console.log(`최신 파일에서 데이터를 파싱 및 저장: ${latestFilePath}`);


  let soapMessageJson = [];
  // CSV 파일을 파싱하고, 데이터베이스에 저장할 데이터를 가져옴
  parseCSVFile(latestFilePath, async (parsedData) => {
    // let soapMessageJson = [];
    if (parsedData.length > 0) { // 데이터가 있는 경우
      for(const row of parsedData){
        await new Promise((resolve) => {
          let { farmNum, houseNum, averTemp, humidity, waterIntake, feedIntake, siloWeight, birdWeight, dateTime } = row;
          let makrId = 'samwoo';
          
          const selectQuery = `SELECT * FROM CTIFARMS WHERE lsindRegistNo = ? AND stallNo = ?`;
          connection.query(selectQuery,[farmNum, houseNum],(err,results)=>{
            if(err){
              console.log('데이터 조회 중 오류:', err);
              return;
            }
            if(results.length>0){
              const result = results[0];
              ctiDestination = result.destination;
              if(result.destination === 'chukpyoungwon'){
                // 각 CSV 열을 데이터베이스 필드에 매핑
                const query = `INSERT INTO CTIBIGDATA (farmNum, houseNum, temperature, humidity, waterIntake, feedIntake, siloWeight, birdWeight, mesureDt)
                VALUES (?,?,?,?,?,?,?,?,?)`;
                // mesureval01=averTemp, 02=humidity 03=hourly water intake 04=hourly feed intake, 05=silo weight, 06=bird scale, mesureDt=dateTime
                // SQL 쿼리를 실행해 데이터베이스에 삽입 
                connection.query(query, [farmNum, houseNum, averTemp, humidity, waterIntake, feedIntake, siloWeight, birdWeight, dateTime], (err) => {
                  if (err) {
                    console.error('데이터 삽입 중 오류:', err);
                    return;
                  }
                  console.log('CTI Data has been inserted to DB.');
                  soapMessageJson.push(
                    {
                      lsindRegistNo:farmNum, itemCode:result.itemCode, markId:makrId, eqpmnCode:'ES01', eqpmnEsntlSn:'', eqpmnNo:result.eqpmnNo, 
                      stallTyCode:result.stallTyCode, stallNo:result.stallNo, roomNo:result.roomNo, roomDtlNo:result.roomDtlNo, mesureDt:dateTime, mesureVal01: averTemp,
                      mesureVal02: '', mesureVal03: '', mesureVal04: '', mesureVal05: '', mesureVal06: '', mesureVal07: '', mesureVal08: '', mesureVal09: '', mesureVal10: '',
                      mesureVal11: '', mesureVal12: '', mesureVal13: '', mesureVal14: '', mesureVal15: ''
                    }
                  );
                  soapMessageJson.push(
                    {
                      lsindRegistNo:farmNum, itemCode:result.itemCode, markId:makrId, eqpmnCode:'ES02', eqpmnEsntlSn:'', eqpmnNo:result.eqpmnNo, 
                      stallTyCode:result.stallTyCode, stallNo:result.stallNo, roomNo:result.roomNo, roomDtlNo:result.roomDtlNo, mesureDt:dateTime, mesureVal01: humidity,
                      mesureVal02: '', mesureVal03: '', mesureVal04: '', mesureVal05: '', mesureVal06: '', mesureVal07: '', mesureVal08: '', mesureVal09: '', mesureVal10: '',
                      mesureVal11: '', mesureVal12: '', mesureVal13: '', mesureVal14: '', mesureVal15: ''
                    }
                  );
                  soapMessageJson.push(
                    {
                      lsindRegistNo:farmNum, itemCode:result.itemCode, markId:makrId, eqpmnCode:'AF02', eqpmnEsntlSn:'', eqpmnNo:result.eqpmnNo, 
                      stallTyCode:result.stallTyCode, stallNo:result.stallNo, roomNo:result.roomNo, roomDtlNo:result.roomDtlNo, mesureDt:dateTime, mesureVal01: waterIntake,
                      mesureVal02: '사용량', mesureVal03: '', mesureVal04: '', mesureVal05: '', mesureVal06: '', mesureVal07: '', mesureVal08: '', mesureVal09: '', mesureVal10: '',
                      mesureVal11: '', mesureVal12: '', mesureVal13: '', mesureVal14: '', mesureVal15: ''
                    }
                  );
                  soapMessageJson.push(
                    {
                      lsindRegistNo:farmNum, itemCode:result.itemCode, markId:makrId, eqpmnCode:'AF05', eqpmnEsntlSn:'', eqpmnNo:result.eqpmnNo, 
                      stallTyCode:result.stallTyCode, stallNo:result.stallNo, roomNo:result.roomNo, roomDtlNo:result.roomDtlNo, mesureDt:dateTime, mesureVal01: feedIntake,
                      mesureVal02: '', mesureVal03: '', mesureVal04: '', mesureVal05: '', mesureVal06: '', mesureVal07: '', mesureVal08: '', mesureVal09: '', mesureVal10: '',
                      mesureVal11: '', mesureVal12: '', mesureVal13: '', mesureVal14: '', mesureVal15: ''
                    }
                  );
                  soapMessageJson.push(
                    {
                      lsindRegistNo:farmNum, itemCode:result.itemCode, markId:makrId, eqpmnCode:'AF01', eqpmnEsntlSn:'', eqpmnNo:result.eqpmnNo, 
                      stallTyCode:result.stallTyCode, stallNo:result.stallNo, roomNo:result.roomNo, roomDtlNo:result.roomDtlNo, mesureDt:dateTime, mesureVal01: siloWeight,
                      mesureVal02: '', mesureVal03: '', mesureVal04: '', mesureVal05: '', mesureVal06: '', mesureVal07: '', mesureVal08: '', mesureVal09: '', mesureVal10: '',
                      mesureVal11: '', mesureVal12: '', mesureVal13: '', mesureVal14: '', mesureVal15: ''
                    }
                  );
                  soapMessageJson.push({
                      lsindRegistNo:farmNum, itemCode:result.itemCode, markId:makrId, eqpmnCode:'PC07', eqpmnEsntlSn:'', eqpmnNo:result.eqpmnNo, 
                      stallTyCode:result.stallTyCode, stallNo:result.stallNo, roomNo:result.roomNo, roomDtlNo:result.roomDtlNo, mesureDt:dateTime, mesureVal01: birdWeight,
                      mesureVal02: '', mesureVal03: '', mesureVal04: '', mesureVal05: '', mesureVal06: '', mesureVal07: '', mesureVal08: '', mesureVal09: '', mesureVal10: '',
                      mesureVal11: '', mesureVal12: '', mesureVal13: '', mesureVal14: '', mesureVal15: ''
                  });
                  // resolve();

                  // console.log('aaaaaaaaaaaaaaaaa: ',soapMessageJson);
                });
              }else{
                console.log('destination: ', result.destination);
                console.log('No data sending is needed. terminating process.');
                // resolve();
              }

            }
          });

          resolve();
        });
      }
      console.log('bbbbbbbbbbbbbbbbbb:',soapMessageJson);
      sendSoapMessage(soapMessageJson);
    }
  });
}
node.js asynchronous async-await promise
1个回答
0
投票

问题是您的代码不会等待

connection.query
的内部调用来执行为其提供的回调函数。

为了解决这个问题,promisify采用异步执行回调函数的函数会更优雅。然后你可以使用

await
来扁平化你的代码。

这是如何运作的:

// Promisify asynchronous callback functions
const queryPromise = (connection, sqlQuery, params) => new Promise((resolve, reject) =>
    connection.query(sqlQuery, params, (err, results) => err ? reject(err) : resolve(results))
);

const parseCSVFilePromise = (path) => new Promise((resolve) => 
    parseCSVFile(path, resolve)
);

// Make function async
async function parseAndSaveCti(product) {
  const latestFile = getLatestFile(ctiDir, product.fileType);
  if (!latestFile) {
    console.log('CTI: CSV File not found.');
    return;
  }

  if (product.lastProcessedFile === latestFile){
    console.log(`CTI ${product.name} parsing error: No new files found. Terminate parsing.`);
    return;
  }

  ctiController.lastProcessedFile = latestFile;
  const latestFilePath = path.join(ctiDir, latestFile);
  const parsedData = await parseCSVFilePromise(latestFilePath);
  const soapMessageJson = [];
  for (const row of parsedData) {
    const { farmNum, houseNum, averTemp, humidity, waterIntake, feedIntake, siloWeight, birdWeight, dateTime } = row;
    const selectQuery = `SELECT * FROM CTIFARMS WHERE lsindRegistNo = ? AND stallNo = ?`;
    let results;
    try {
      results = await queryPromise(connection, selectQuery, [farmNum, houseNum]);
    } catch (err) {
      console.log('Error during data selection:', err);
      return;
    }
    const ctiDestination = results[0]?.destination;
    if (ctiDestination !== 'chukpyoungwon') {
      console.log('destination: ', ctiDestination, '. No data sending is needed. Skipping.');
      continue;
    }
    const insertQuery = `INSERT INTO CTIBIGDATA (farmNum, houseNum, temperature, humidity, waterIntake,
                                                 feedIntake, siloWeight, birdWeight, mesureDt)
                         VALUES (?,?,?,?,?,?,?,?,?)`;
    try {
      await queryPromise(connection, insertQuery, [farmNum, houseNum, averTemp, humidity, waterIntake, 
                                                   feedIntake, siloWeight, birdWeight, dateTime]);
    } catch (err) {
      console.error('Error during data insertion:', err);
      return;
    }
    // Add your objects to insert here (I omitted them here as not relevant to the fix)
    soapMessageJson.push( { lsindRegistNo:farmNum, ......... },
                          { lsindRegistNo:farmNum, ......... },
                          { lsindRegistNo:farmNum, ......... },
                          // ...
                        );
  }
  if (soapMessageJson.length) sendSoapMessage(soapMessageJson);
}

我无法测试此代码,因为您的代码中有几个未知数,包括

getLatestFile
ctiDir
ctiController
path
connection
sendSoapMessage

© www.soinside.com 2019 - 2024. All rights reserved.