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

时间:2020-05-14 14:18:21

标签: node.js express async-await render router

我正在尝试获取一条路径,以等待另一个模块中的异步功能在渲染运行之前返回,但是无论我做什么,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。有什么办法可以做到这一点?

2 个答案:

答案 0 :(得分:1)

由于accessSpreadSheetasync函数,因此您需要await或在getData函数以及类似的方法中返回诺言(如Patrick Roberts在评论中所建议)。路由器。

使用异步等待,您可以按以下方式更新代码(未经测试)

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})
})

答案 1 :(得分:1)

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

 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中,您需要返回一个在路由器中调用时将被解决的Promise。

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

最后在accessSpreadsheet()中,我看不到您返回解析后的数据的地方。

  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很重要。

希望它能提供一些帮助!