Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 承诺期间(fs readstream)_Javascript_Node.js_Promise_Async Await_Fs - Fatal编程技术网

Javascript 承诺期间(fs readstream)

Javascript 承诺期间(fs readstream),javascript,node.js,promise,async-await,fs,Javascript,Node.js,Promise,Async Await,Fs,我为自动上传备份文件(在Backblaze上)制作了一个脚本 制作一个脚本,将完整文件加载到常量中,当文件大小增加(从1 GB增加到3gb以上)时,拆分字符串并上载每个部分。我的脚本崩溃 我试图完全异步地重写脚本 我这样写: 异步getFileInfoAndUploadPart(路径,sizeChunk=1024){ 常数信息={ sha1:null, 尺寸:0, 零件号:0, 第1部分:{}, }; 返回新承诺(解决=>{ const shasumGlobal=crypto.createHas

我为自动上传备份文件(在Backblaze上)制作了一个脚本

制作一个脚本,将完整文件加载到
常量中,当文件大小增加(从1 GB增加到3gb以上)时,拆分字符串并上载每个部分。我的脚本崩溃

我试图完全异步地重写脚本

我这样写:

异步getFileInfoAndUploadPart(路径,sizeChunk=1024){ 常数信息={ sha1:null, 尺寸:0, 零件号:0, 第1部分:{}, }; 返回新承诺(解决=>{ const shasumGlobal=crypto.createHash('sha1'); 日志(路径,sizeChunk); 常量输入=fs.createReadStream(路径); input.on('readable',()=>{ console.log('1'); 让块; while((chunk=input.read(sizeChunk))!==null){ console.log('2'); const tempShasum=crypto.createHash('sha1'); shasumGlobal.update(chunk); tempShasum.update(块); info.partNumber+=1; info.partSha1[info.partNumber]=tempShasum.digest('hex'); } console.log('3'); info.sha1=shasumGlobal.digest('hex'); 解决(信息); }); }); }
但承诺在
之前解决,而
:/
什么是正确的方法,使这同时完成之前,我的承诺

(在上传每个部件时,我需要在此过程中调用异步函数)

编辑

最后,我使用了以下方法:

异步getFileInfoAndUploadPart(路径,sizeChunk=1024,文件ID='xxx'){ 返回新承诺(解决=>{ 常数信息={ fileId:fileId, sha1:null, 尺寸:0, 零件号:0, 第1部分:{}, }; const input=fs.createReadStream(路径{highWaterMark:sizeChunk}); const shasumGlobal=crypto.createHash('sha1'); input.on('data',异步数据块=>{ const shasumPart=await crypto.createHash('sha1'); 等待shasumPart.update(数据块); 等待shasumGlobal.update(dataChunk); info.partNumber+=1; info.partSha1[info.partNumber]=shasumPart.digest('hex'); }); input.on('end',()=>{ info.sha1=shasumGlobal.digest('hex'); 解决(信息); }); }); }
编辑2:

上面的代码工作不好

首先,您需要在播放数据时暂停流,并在可以处理下一部分时恢复流

第二个错误: 如果你用10个10月的文件来尝试这段代码,并使用5个10月的区块

第一次触发“数据”事件=>ok

第二次触发“数据”事件=>ok

触发“结束”事件=>ok

但是如果您想将流分成3部分(Math.ceil(fileSize/chunkSize)=>4+4+2,则只需将最后一部分缩短)

第一次触发“数据”事件=>ok

第二次触发“数据”事件=>ok

您第三次触发“数据”事件,但是 您到达流的末尾,因此在 同时

只有在“数据”逻辑完成后,我才找到触发“结束”事件的任何解决方案

因此,我认为我预先计算了区块的数量,并在“数据”事件中实现了我的“结束”逻辑,当我在最后一个区块上时…

async getFileInfoAndUploadPart(path,sizeChunk=1024,fileId='xxx'){
返回新承诺(解决=>{
const stats=fs.statSync(路径);
常数信息={
fileId:fileId,
sha1:null,
尺寸:0,
零件号:0,
零件号理论:Math.ceil(统计数据、尺寸/尺寸),
第1部分:{},
};
const input=fs.createReadStream(路径{highWaterMark:sizeChunk});
const shasumGlobal=crypto.createHash('sha1');
input.on('data',异步数据块=>{
input.pause();
const shasumPart=crypto.createHash('sha1');
shasumPart.update(数据块);
shasumGlobal.update(dataChunk);
info.partNumber+=1;
info.partSha1[info.partNumber]=shasumPart.digest('hex');
//强制传递信息对象的副本。
//等待这个.uploadWithRetry(dataChunk,{…info},parameters.getConfig('maxRetry'),parameters.getConfig('waitbeforetry'));
等待这个。debug()。然后(()=>{
log({…info});
});
input.resume();
if(信息零件号===信息零件号理论){
console.log('end');
info.sha1=shasumGlobal.digest('hex');
解决(信息);
}
});
});
}
PS:调试是这个函数的一部分

异步调试(时间=1000){ 返回新承诺(解决=>{ 设置超时(()=>{ 解决(); },时间); }); };
while循环结束之前,您的承诺不会得到解决。可能存在这样一种情况:promise回调中的代码失败,因此promise可能会拒绝,而不是解决。尝试将
.catch(err=>console.log(err))
添加到
getFileInfoAndUploadPart
函数返回的结果中,并检查脚本崩溃是什么错误,因为我调用了
shasumGlobal.update(chunk)
shasumGlobal.digest('hex')之后(在我的控制台中,我看到了<代码> 1代码/代码>,代码> 3 <代码>,然后返回我的函数……然后崩溃……(从来没有看到<代码> 2代码/代码……)我们用节点中的异步迭代器直接支持迭代流,考虑使用<代码>等待< /代码>