axios切片上传怎么才能实现同步上传,下一片上传文件需要根据上一片的返回状态码,再决定是否上传?
我需要怎么把以下的代码,改成问题中的需求呢?
forEach和async和await在一起不能实现同步,
不太懂前端,,很抓狂,求大神仔细讲解
这是在开始上传文件之前,需要先获取文件的在服务器的中状态信息,查看是否已经上传过。
{iCode: 0, strMessage: "Success",…}iCode: 0
objData: [
{iFileId: 0, strFileName: "1_1000080.zyp", lSize: 101053451, strFileType: "zyp",…}]
0: {iFileId: 0, strFileName: "1_1000080.zyp", lSize: 101053451, strFileType: "zyp",…}
iFileId: 0
lSize: 101053451
listFileSliceInfo: [{lSize: 101053451, strFilePath: "", strStatus: "complete", lProgress: 0}]
0: {lSize: 101053451, strFilePath: "", strStatus: "complete", lProgress: 0}
lProgress: 0
lSize: 101053451
strFilePath: ""
strStatus: "complete"
strFileName: "1_1000080.zyp"
strFileType: "zyp"
strMessage: "Success"
emitHandle() { //上传文件
let iUpdadeState = 0;
this.testFilesStatus.forEach((item, index) => {
let obj = item[0].listFileSliceInfo[0];
if (obj.strStatus == "none") {
iUpdadeState = 0;
} else {
iUpdadeState = 1;
}
let lSize = this.testFiles[index].file.size;
const sectionSize = 1 * 1024 * 1024;
const sectionTotal = Math.ceil(lSize / sectionSize);
for (let i = 0; i < sectionTotal; i++) {
const startSize = i * sectionSize; // 切片开始位置
const endSize =
i === sectionTotal - 1 ? lSize : (i + 1) * sectionSize;
let fileData = this.testFiles[index].file.slice(startSize, endSize);
if (this.progress) {
let formData = new FormData();
formData.append("file", fileData);
formData.append("iUpdadeState", iUpdadeState);
formData.append("iSlideDocumentId", item[0].iFileId);
formData.append("strFilePath", "");
FileUploadHandler(formData, (spreed) => {
// 总大小
let loaded = 0;
loaded += spreed.loaded;
let sep =
(((loaded / this.testFiles[index].file.total) * 100) | 0) +"%";
this.testFiles[index].file.status = sep;
});
}
}
});
},
回答:
把上传单个分片文件写成一个递归函数。
回答:
forEach
自然是不可以的,因为它不会受回调函数返回值的影响,可以用 for...in
或者 for...of
。
之前回答了一个问题,提供了一个异步队列的方案:
function queueGen(processor){ const taskQueue = [];
let pendingFlag = false;
async function handler([param, callback, errorHandler]){
try{
callback(await processor(param));
} catch(err) {
if(errorHandler){
errorHandler(err)
}
}
consumer();
}
function consumer(){
if(!taskQueue.length){
pendingFlag = false;
return
}
handler(taskQueue.shift());
}
return function addTask(callback, param, errorHandler){
taskQueue.push([param, callback, errorHandler]);
if(!pendingFlag) {
pendingFlag = true;
consumer();
}
}
}
如果不考虑传输失败的问题的话,放到这里是可以直接用的:
// 假设这个 upload 里的回调函数就是 Promise 化的上传函数const upload = queueGen(function asyncTimeOut(delay = 1e3){
return new Promise(function(resolve, reject){
setTimeout(resolve, delay)
// 成功的时候执行 resolve
// 失败的时候执行 reject
});
});
// 直接按顺序 upload 就可以了,使用 forEach 也无妨
for(let i = 0;i< 10; i++){
const delay = (10 % i) * 1e3
upload(() => console.log(`第${i + 1}个任务,延迟了${delay}毫秒`), delay);
}
如果需要考虑失败重试的话需要递归实现,这个方案也可以使用,但是没有啥优势:
// 假设这个 upload 里的回调函数就是 Promise 化的上传函数const upload = queueGen(function asyncTimeOut(delay = 1e3){
return new Promise(function(resolve, reject){
setTimeout(resolve, delay)
// 成功的时候执行 resolve
// 失败的时候执行 reject
});
});
// 假设这是全部分片
const sliceArray = [];
let currentSlice = sliceArray.shift();
// 上传单个分片
const singleUpload = slice => {
upload(
() => {
// 上传成功,传下一个分片,直到没有分片
currentSlice = sliceArray.shift();
if(currentSlice){
singleUpload(currentSlice)
} else {
// 这里说明全部分片都传完了,可以执行成功的逻辑
}
},
slice,
() => {
// 上传失败,重试
singleUpload(currentSlice)
}
)
}
以上是 axios切片上传怎么才能实现同步上传,下一片上传文件需要根据上一片的返回状态码,再决定是否上传? 的全部内容, 来源链接: utcz.com/p/935391.html