我正在尝试提取一些存储在Firebase存储中的图像,创建可公开访问的网址,然后将它们添加到一个数组中,该数组将在我渲染模板时传入。但是,每次我的模板在拉取数据之前首先呈现时,数组都是空的。我基本上需要找到一种方法来呈现模板,只有在所有数据库拉取完成后,我不知道如何。我已经投入异步等待作为尝试解决此问题的一种手段,但我没有运气。
这是我的代码:
async function readFiles () {
const [files] = await bucket.getFiles({ prefix: 'Resources/'});
files.forEach(file => {
//we have to get a signed public url in order to access the files stored in the cloud
file.getSignedUrl(signConfig, function(err, url) {
if (err) {
console.error(err);
return;
}
// The file is now available to read from this URL.
request(url, function(err, resp) {
resources.push(url) //append all the publicly avaialbe url's to the resources array
resp.statusCode = 200;
console.log("done request")
});
});
});
console.log("DONE READ FILES");
};
async function returnIndex() {
await readFiles(); //wait until read files is finished
console.log("TCL: returnIndex -> resources", resources);
res.render('advertiser/index.html', {resources: resources});
};
returnIndex();
然后这是我的输出(存储在我的数据库中的 5 个东西(,基本上表明在我的模板渲染后,所有公共 url 都添加到数组中:
DONE READ FILES
TCL: returnIndex -> resources []
done request
done request
done request
done request
done request
找到了一个解决方案。这是为了将超时设置为 0 毫秒...不确定为什么会这样,但我认为这与事件循环中的微任务与宏任务的差异有关......承诺是微任务,而 Settimeout 是宏任务,因此 Settimeout 将最后执行,从而正确提取数据库中的信息
var resources = new Array();
const [files] = await bucket.getFiles({ prefix: 'Resources/'});
// Lists all resources in their bucket
function readFiles () {
files.forEach(file => {
file.getSignedUrl(signConfig, function(err, url) {
if (err) {
console.error(err);
return;
}
resources.push(url)
// The file is now available to read from this URL.
request(url, function(err, resp) {
resp.statusCode = 200;
});
});
});
setTimeout(function(){res.render('advertiser/index.html', {resources: resources})}, 0);
};
readFiles();