如何在渲染前获取 Express Node 路由以等待功能

How to get Express Node route to wait for function before rendering

我正在尝试在渲染运行之前获取等待另一个模块中的异步函数到 return 的路由,但无论我做什么,res.render 总是先运行。 这是我当前的代码,它实际上只是冻结并且从不加载:

router.get('/', function(req, res, next) {
  try {
    const cities = spreadsheet.getData()

  } catch(err) {
    console.log(err)
  }

  res.render('index', { cities: cities})
})

它正在等待的函数是这样的:

exports.getData = function () {
  parsedData = [];
  accessSpreadsheet().then(function(data) {
    console.log(parsedData)
    return parsedData;
  });
};

const accessSpreadsheet = async() => {
  await doc.useServiceAccountAuth({
      client_email: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL,
      private_key: process.env.GOOGLE_PRIVATE_KEY,
    });
  const loadedDoc =  await doc.loadInfo();
  sheet = await doc.sheetsByIndex[0];
  const cells = await sheet.loadCells(allCells[cellsIndex]);
  const data = await parseData();
  const moreCells = await checkNextCells()

  return;
}

首先运行渲染,parsedData 在控制台打印。我还尝试使路由异步,并在回调中尝试 res.render 。有什么办法可以做到这一点吗?

由于 accessSpreadSheet 是一个 async 函数,您需要 await 或 return 承诺(正如 Patrick Roberts 在评论中所建议的那样),在 getData功能,和路由器类似。

使用 async await 你可以更新你的代码如下(未测试)

exports.getData = async function () {
  parsedData = [];
  parsedData = await accessSpreadSheet();
  return parsedData;
};

const accessSpreadsheet = async() => {
  await doc.useServiceAccountAuth({
      client_email: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL,
      private_key: process.env.GOOGLE_PRIVATE_KEY,
    });
  const loadedDoc =  await doc.loadInfo();
  sheet = await doc.sheetsByIndex[0];
  const cells = await sheet.loadCells(allCells[cellsIndex]);
  const data = await parseData();
  const moreCells = await checkNextCells()

  return;
}

在路由器中

router.get('/', async function(req, res, next) {
  let cities;
  try {
    cities = await spreadsheet.getData()

  } catch(err) {
    console.log(err)
  }

  res.render('index', { cities: cities})
})

在您的路由器中,spreadsheet.getData() 是异步的,您需要使用 async/wait 处理它,这将要求您的回调是异步的。

 router.get('/', async function(req, res, next) {
  try {
    const cities = await spreadsheet.getData();

    res.render('index', { cities: cities}) // moved this to inside a try block

  } catch(err) {
    console.log(err)
    // you need to handle the exception here, return error message etc
  }

})

在 getData 中,您需要 return 一个在路由器中调用时将被解析的承诺。

exports.getData = async function () {
    let parsedData = [];  
   try {
     parsedData = await accessSpreadsheet();
    } catch (exc) {
      // handle exception here
    }
   return parsedData;
};

终于在 accessSpreadsheet() 中,我没看到你在哪里 return 分析了数据。

  const accessSpreadsheet = async() => {
  try{
  await doc.useServiceAccountAuth({
      client_email: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL,
      private_key: process.env.GOOGLE_PRIVATE_KEY,
    });
  let loadedDoc =  await doc.loadInfo();
  let sheet = await doc.sheetsByIndex[0];
  let cells = await sheet.loadCells(allCells[cellsIndex]); // cellsIndex is not defined
  let data = await parseData(); // are you to pass the sheet? do not know how parsedData() works
  let moreCells = await checkNextCells()

  return data; // assuming data is what is meant to be returned
} catch(exc) {
   // probably return null or re-raise exception
}
}

在 NodeJS 中处理异步代码时始终使用 try/catch 或 then/catch 很重要。

希望它有所启发!