javascript - 使用 For 循环将多个文件上传到 Google Cloud Storage
问题描述
我正在尝试将多个文件上传到 Google Cloud Storage。我正在使用 for 循环来处理我要上传的文件列表中的每个文件。
但是,问题在于 for 循环不会暂停以等待上传完成,然后再继续进行下一次上传。它最终会上传它们,但是,for 循环更早完成,然后将 empty 发送回客户端urlList
。
如何让它暂停并等待每个上传过程,然后再转到 for 循环中的下一个文件?
const processFile = require('../middleware');
const { format } = require('util');
let uuidv4 = require('uuid/v4');
const Cloud = require('@google-cloud/storage');
const { Storage } = Cloud;
const storage = new Storage({
keyFilename: './xxx.json',
projectId: 'xxx'
});
const bucket = storage.bucket('xxx');
exports.upload = async (req, res) => {
const urlList = [];
await processFile(req, res); //multer
for (var i = 0; i < req.files.length; i++) {
if (!req.files[i]) {
return res.status(400).send({ message: 'Please upload a file!' });
}
const { originalname, buffer } = req.files[i];
var filename = originalname
.toLowerCase()
.split(' ')
.join('-');
filename = uuidv4() + '-' + filename;
console.log(filename);
const blob = bucket.file(filename);
const blobStream = blob.createWriteStream({
resumable: false
});
blobStream.on('error', err => {
res.status(500).send({ message: err.message });
});
blobStream.on('finish', async data => {
const publicUrl = format(
`https://storage.googleapis.com/${bucket.name}/${blob.name}`
);
urlList.push(publicUrl);
try {
await bucket.file(filename).makePublic();
} catch (err) {
console.log('failed to make it public');
reject(err);
}
});
blobStream.end(buffer);
}
return res.status(200).send({
message: 'Uploaded the files successfully',
url: urlList
});
};
解决方案
只需将您的“上传”代码放入循环Promise
中即可await
。否则通过使用on
其中的代码将不会遵循 for 循环。通过使用这种基于事件的代码,您的 for 循环只会通过它并且不能等待它完成。这应该可以解决问题:
const uploadFile = (f) => {
return new Promise((resolve, reject) => {
const { originalname, buffer } = f;
var filename = originalname.toLowerCase().split(" ").join("-");
filename = uuidv4() + "-" + filename;
console.log(filename);
const blob = bucket.file(filename);
const blobStream = blob.createWriteStream({
resumable: false,
});
blobStream.on("error", (err) => {
res.status(500).send({ message: err.message });
reject(err);
});
blobStream.on("finish", async (data) => {
const publicUrl = format(
`https://storage.googleapis.com/${bucket.name}/${blob.name}`
);
try {
await bucket.file(filename).makePublic();
resolve(publicUrl);
} catch (err) {
console.log("failed to make it public");
reject(err);
}
});
blobStream.end(buffer);
});
};
exports.upload = async (req, res) => {
const urlList = [];
await processFile(req, res); //multer
for (var i = 0; i < req.files.length; i++) {
if (!req.files[i]) {
return res.status(400).send({ message: "Please upload a file!" });
}
const publicUrl = await uploadFile(req.files[i]);
urlList.push(publicUrl);
}
return res.status(200).send({
message: "Uploaded the files successfully",
url: urlList,
});
};
推荐阅读
- javascript - Tailwindcss 不适用于 next.js;配置有什么问题?
- datatables - Power BI 比较两个表并显示第一个表中缺失的行
- javascript - 错误:400(错误请求)使用 fetch 将数据发布到本地服务器
- .net - Xamarin 表单 - 导航到另一个页面
- spring-boot - 让stream.map返回List Spring boot?
- mysql - 插入随机连接选择查询
- html - 更改每个子 div 的背景图像
- excel - 从单元格公式调用时,VBA 在单元格中插入默认值
- r - 使用 dbWriteTable 使用现有键写入表时出错
- javascript - JS:添加带有动态文本输入的列表元素