如何在渲染前获取 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 很重要。
希望它有所启发!
我正在尝试在渲染运行之前获取等待另一个模块中的异步函数到 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 很重要。
希望它有所启发!