You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

resolve在其他函数完成前被调用,如何确保其在操作完成后执行?

Fixing Premature Resolve in Your downloadFile Function

It sounds like you’re hitting a classic asynchronous flow issue here—your resolve() is firing before the file-writing operation actually finishes, which is why the downloaded file comes up empty. Let’s break down how to fix this.

Root Cause

Asynchronous operations like database connections, data fetching, and file I/O don’t block your code’s execution. If you call resolve() outside the callback of your file-write operation, it will trigger immediately, even before the file has been populated with data.

Corrected Callback-Based Code

Here’s how to adjust your function to ensure resolve() only runs after all async work (including writing the file) is complete:

var downloadFile = (oracledb, connectionAttributes, responsem, files) => {
  return new Promise((resolve, reject) => {
    // Step 1: Establish database connection
    oracledb.getConnection(connectionAttributes, (connError, connection) => {
      if (connError) {
        console.error('Failed to get DB connection:', connError);
        return reject(connError); // Reject on connection failure
      }

      // Step 2: Fetch data from Oracle (adjust query to match your use case)
      const fetchQuery = 'SELECT * FROM your_target_table';
      connection.execute(fetchQuery, (queryError, result) => {
        if (queryError) {
          console.error('Query failed:', queryError);
          connection.close(); // Clean up connection before rejecting
          return reject(queryError);
        }

        // Step 3: Convert query result to Excel-compatible data (your existing logic here)
        const excelContent = convertToExcelFormat(result.rows);

        // Step 4: Write content to file, only resolve once this finishes
        const fs = require('fs');
        fs.writeFile(files.outputPath, excelContent, (writeError) => {
          connection.close(); // Always close the DB connection, even if writing fails
          if (writeError) {
            console.error('Failed to write file:', writeError);
            return reject(writeError);
          }

          // Finally, resolve after file write succeeds
          resolve({ 
            message: 'File ready for download', 
            filePath: files.outputPath 
          });
        });
      });
    });
  });
};

Key Fixes Explained

  • Move resolve() inside the file-write callback: This ensures we only signal success once the file has been fully saved to disk.
  • Proper error handling: Reject the promise at every failure point (connection error, query error, file-write error) and clean up resources like the database connection to avoid leaks.
  • Chain async operations: Each step (connection → query → file write) is nested inside the previous step’s callback, so we wait for one to finish before starting the next.

Bonus: Cleaner Async/Await Version

If you want to avoid callback hell, you can promisify your async functions and use async/await for more readable code:

const { promisify } = require('util');
const fs = require('fs');
const writeFileAsync = promisify(fs.writeFile);
const getConnectionAsync = promisify(oracledb.getConnection);

var downloadFile = async (oracledb, connectionAttributes, responsem, files) => {
  let connection;
  try {
    // Get DB connection
    connection = await getConnectionAsync(connectionAttributes);
    
    // Execute query
    const fetchQuery = 'SELECT * FROM your_target_table';
    const result = await promisify(connection.execute).bind(connection)(fetchQuery);
    
    // Convert to Excel format
    const excelContent = convertToExcelFormat(result.rows);
    
    // Write to file
    await writeFileAsync(files.outputPath, excelContent);
    
    // Resolve after all steps complete
    return { message: 'File ready for download', filePath: files.outputPath };
  } catch (error) {
    console.error('Download failed:', error);
    throw error; // Throwing rejects the promise automatically
  } finally {
    // Ensure connection is closed even if an error occurs
    if (connection) {
      await promisify(connection.close).bind(connection)();
    }
  }
};

This approach makes the flow linear and easier to debug, while still guaranteeing all operations finish before resolving the promise.

内容的提问来源于stack exchange,提问作者Prajyod Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:15:28