//获取数据类型
const GetDataType = any => {
let str = Object.prototype.toString.call(any);
return str.slice(8, -1);
}
//uploadFile方法基础配置
const uploadBaseConfig = {
file: File,
maxSize: 4 * 1024 * 1024,
taskLength: 1,
}
//文件上传方法
export async function uploadFile(config = uploadBaseConfig) {
return new Promise(resolve => {
let taskResolve = []; //所有请求的相应
if (GetDataType(config) === "File") {
config = {
...uploadBaseConfig,
file: arguments[0],
...arguments[1],
};
}
const { file, maxSize, taskLength } = config; //uploadFile 请求配置对象
if (GetDataType(file) !== "File") {
return Promise.reject(new Error("文件不能为空"));
};
//请求方法
const uploadMethod = formData => axios({
method: "post",
url: `/index/util/upload`,
data: formData,
headers: {
"Content-Type": "multipart/form-data"
},
});
// 小于4Mb直接传
if (file.size <= maxSize) {
const form = new FormData();
form.append("file", file);
uploadMethod(form).then(res => {
resolve(res);
});
return
}
//Symbol兼容处理
const makeIterator = arr => {
if (/native code/.test(Symbol.toString())) {
return arr[Symbol.iterator]();
}
let nextIndex = 0;
return {
next() {
if (nextIndex < arr.length) {
return { value: arr[nextIndex++], done: false }
}
return { value: undefined, done: true }
}
}
};
//请求队列
const task = arr => {
const { value } = arr.next();
if (value) {
Promise.all(value.map(item => uploadMethod(item))).then(result => {
taskResolve = taskResolve.concat(result);
setTimeout(() => task(arr), 1000 * 5);
});
} else {
resolve(taskResolve)
}
};
const length = Math.ceil(file.size / maxSize); //文件分片长度
const taskArrLength = Math.ceil(length / taskLength);//promise任务队列长度
//切割文件对象
const arr = [...new Array(length)].map((item, index) => {
const start = index * maxSize;
const end = start + maxSize;
const fileContent = new File(// 文件内容
[file.slice(start, end)],
file.name,
{ type: file.type }
);
const form = new FormData();
form.append("file", fileContent);
return form;
});
// 队列数组
const taskArr = [... new Array(taskArrLength)].map((item, index) => {
const start = index * taskLength;
const end = start + taskLength;
return arr.slice(start, end);
});
const tasklist = makeIterator(taskArr); //生成任务队列
task(tasklist);
})
};