【发布时间】:2020-01-29 13:17:43
【问题描述】:
我制作了一个自动上传备份文件的脚本(在 Backblaze 上)...
制作一个将完整文件加载到const 的脚本,拆分字符串并在文件大小增加(从 1 到超过 3gb)时上传每个部分,我的脚本崩溃了。
我尝试完全异步重写脚本。
我写这个:
async getFileInfoAndUploadPart(path, sizeChunk = 1024) {
const info = {
sha1: null,
size: 0,
partNumber: 0,
partSha1: {},
};
return new Promise(resolve => {
const shasumGlobal = crypto.createHash('sha1');
console.log(path, sizeChunk);
const input = fs.createReadStream(path);
input.on('readable', () => {
console.log('1');
let chunk;
while ((chunk = input.read(sizeChunk)) !== null) {
console.log('2');
const tempShasum = crypto.createHash('sha1');
shasumGlobal.update(chunk);
tempShasum.update(chunk);
info.partNumber += 1;
info.partSha1[info.partNumber] = tempShasum.digest('hex');
}
console.log('3');
info.sha1 = shasumGlobal.digest('hex');
resolve(info);
});
});
}
但承诺在while 之前解决:/
在返回我的承诺之前完成此操作的正确方法是什么?
(我打算在这个过程中调用一个异步函数来上传每个部分)
编辑
最后我使用了这个方法:
async getFileInfoAndUploadPart(path, sizeChunk = 1024, fileId = 'xxx') {
return new Promise(resolve => {
const info = {
fileId: fileId,
sha1: null,
size: 0,
partNumber: 0,
partSha1: {},
};
const input = fs.createReadStream(path, { highWaterMark: sizeChunk });
const shasumGlobal = crypto.createHash('sha1');
input.on('data', async dataChunk => {
const shasumPart = await crypto.createHash('sha1');
await shasumPart.update(dataChunk);
await shasumGlobal.update(dataChunk);
info.partNumber += 1;
info.partSha1[info.partNumber] = shasumPart.digest('hex');
});
input.on('end', () => {
info.sha1 = shasumGlobal.digest('hex');
resolve(info);
});
});
}
编辑 2:
上面的代码运行不好……
首先,您需要在播放数据时暂停流,并在可以处理下一部分时恢复流...
第二个错误: 如果您使用 10 oct 文件尝试此代码,并使用 5 oct 块...
你第一次触发“数据”事件 => 好的
您第二次触发“数据”事件 => 好的
您触发了“结束”事件 => 好的 ...
但是如果你想将流分成 3 部分( Math.ceil(fileSize/chunkSize) => 4 + 4 + 2 ,只有最后一部分需要更短)
你第一次触发“数据”事件 => 好的
您第二次触发“数据”事件 => 好的
您第三次触发了“数据”事件,但是 您到达流的末尾,因此您在 同时...
只有在我的“数据”逻辑完成后,我才找到触发“结束”事件的任何解决方案...
所以我想我预先计算了块的数量,并在我在最后一个块上时在“数据”事件中实现我的“结束”逻辑......
【问题讨论】:
-
你的承诺在 while 循环结束之前没有解决。可能存在您的代码在承诺回调中失败的情况,因此承诺可能会拒绝,而不是解决。尝试将
.catch(err => console.log(err))添加到getFileInfoAndUploadPart函数返回的结果中并检查错误是什么 -
脚本崩溃是因为我在
shasumGlobal.digest('hex');之后调用了shasumGlobal.update(chunk);(并且在我的控制台中我看到了1、3,以及我的函数的返回......然后崩溃了而...。(永远看不到2...) -
我们支持在 Node 中直接使用异步迭代器来迭代流,请考虑将其与
for await一起使用
标签: javascript node.js promise async-await fs