javascript - 使用 Promise.all 为 AWS Node.js 上传创建进度条
问题描述
我一直在玩下面的代码,试图将我当前的 AWS 上传器减少到几行代码。这段代码效果很好,但我真的需要一个进度指示器来监控上传进度,因为对于较大的文件或文件夹上传,用户不知道需要多长时间。
我是新的承诺等待等我当前的代码使用回调。
我在这里看到了这段代码。 ES6 Promise.all 进度
是否可以为每个成功上传的文件获取回调?这样我就可以获取所有要上传的文件的总长度,并基于该增量输出一个进度。
这是我当前的代码。
let AWS = require("aws-sdk");
const fs = require('fs');
const path = require('path');
const s3 = new AWS.S3();
const params = [];
fs.readdirSync('/Users/dave/Desktop/uploadit').forEach(file => {
const {
ext,
name,
dir
} = path.parse(file);
let fl = name.replace(/[^a-z0-9/]/gi, '_').toLowerCase();
params.push({
Bucket: 's3b-south-amercia',
Key: fl + ext,
Body: fs.readFileSync('/Users/dave/Desktop/uploadit/' + file)
});
});
var total_files = params.length;
// Start function
const start = async function(a, b) {
console.time('test');
const responses = await Promise.all(
params.map(param => s3.upload(param).promise())
);
console.timeEnd('test');
}
// Call start
start();
// time aws s3 cp /Users/dave/Desktop/uploadit s3://s3b-south-amercia/ --recursive
// AWS CLI 26.295 / 24.684s
// AWS NODE 27.859s / 20.483
我已经针对 AWS cli line cp 命令测试了代码,它们都有相似的上传时间。
任何帮助或为我指明正确的方向如何使用 promise all 实现回调将不胜感激,也许 promise all 不是为了做到这一点而设计的,我不确定。
谢谢
感谢@nobody 的工作代码;)
let AWS = require("aws-sdk");
const fs = require('fs');
const path = require('path');
const s3 = new AWS.S3();
const params = [];
fs.readdirSync('/Users/dave/Desktop/uploadit').forEach(file => {
const {
ext,
name,
dir
} = path.parse(file);
let fl = name.replace(/[^a-z0-9/]/gi, '_').toLowerCase();
params.push({
Bucket: 's3b-south-amercia',
Key: fl + ext,
Body: fs.readFileSync('/Users/dave/Desktop/uploadit/' + file)
});
});
var progress = 1;
var total_files = params.length;
console.log('total_files', total_files);
const onProgress = async promise => {
const result = await promise;
console.log(progress / total_files * 100 + '%');
progress++;
return result;
};
// Start function
const start = async function(a, b) {
console.time('test');
const responses = await Promise.all(
params.map(param => onProgress(s3.upload(param).promise()))
);
/*const responses = await Promise.all(
params.map(param => s3.upload(param).promise())
);*/
console.timeEnd('test');
}
// Call start
start();
// time aws s3 cp /Users/dave/Desktop/uploadit s3://s3b-south-amercia/ --recursive
// AWS CLI 26.295 / 24.684s
// AWS NODE 27.859s / 20.483
更新:
当您在包含大量文件的文件夹上运行此代码时通知任何使用此代码的人,您几乎肯定会遇到此错误。
RequestTimeTooSkewed:请求时间与当前时间相差过大
我在这里创建了一张票和一个解决方法。
https://github.com/aws/aws-sdk-js/issues/3757
但希望很快就会对 SDK 进行修复。
解决方案
你可以用你自己的函数来包装s3.upload
,只要它返回原始响应,你就可以在Promise.all
.
const onDone = async promise => {
const result = await promise;
console.log("File upload complete");
// Or add +1 to some variable to calculate percentage of completed uploads
return result;
};
const responses = await Promise.all(
params.map(param => onDone(s3.upload(param).promise()))
);
推荐阅读
- python - 有没有办法让多个 IndexedVertexLists 引用相同的顶点,同时具有不同的索引列表
- wordpress - wordpress 主页 url 重定向到本地主机
- google-apps-script - 如何判断 Google 表格是否已共享?
- gcc - 使用 Arm GNU 汇编程序的 Pop Push
- python - 如何使用python以特定频率触发事件
- javascript - 单击项目后如何关闭汉堡菜单?
- python - 带有 Flask/Jinja 的 HTML 中的动态标题(扩展)
- sapui5 - SplitScreen 应用程序中的 SAP UI5 路由和导航
- python - 将动态数据插入 QTableWidget
- python - 错误:在 TensorFlow 安装中启动本地 Bazel 服务器时未定义“http_archive”