gpt4 book ai didi

javascript - 如何在循环内使用回调?

转载 作者:行者123 更新时间:2023-11-30 06:12:48 26 4
gpt4 key购买 nike

背景是我允许用户将多个文件拖到 Dropzone 中。我需要检查每种文件类型。如果其中一个不允许,则设置消息并早点离开。

请看下面的代码开始于 for (let i = 0; i < acceptedFiles.length; i++) {在这个 for 循环中,我调用 reader.onloadend ,这是一个回调。

如何在 for 循环中运行回调?

// Keep it internal
const getMimetype = signature => {
switch (signature) {
case '89504E47':
return 'image/png';
case '47494638':
return 'image/gif';
case '25504446':
return 'application/pdf';
case 'FFD8FFDB':
case 'FFD8FFE0':
return 'image/jpeg';
case '504B0304':
return 'application/zip';
default:
return 'Unknown filetype';
}
};

const onDropAccepted = useCallback(acceptedFiles => {
// reset to default state
resetToDefaultState();

//test
console.log('acceptedFiles', acceptedFiles);

// reader
const reader = new FileReader();
let file;

// Multi
if (config.isMultipleFiles === true) {
// Loop all files and check file types
for (let i = 0; i < acceptedFiles.length; i++) {
file = acceptedFiles[i];
// get 1st 4 byptes
const blob = file.slice(0, 4);
reader.readAsArrayBuffer(blob);

reader.onloadend = evt => {
if (evt.target.readyState === FileReader.DONE) {
const uint = new Uint8Array(evt.target.result);
let bytes = [];
uint.forEach(byte => {
bytes.push(byte.toString(16));
});

const hex = bytes.join('').toUpperCase();
const type = getMimetype(hex);

// type is allowed
if (config.fileTypes.includes(type)) {
setFiles([...files, ...acceptedFiles]);
} else {
// type no good
setIsInvaildFileType(true);
}
}
};
}
} else {
// drop 1 file
if (acceptedFiles.length <= 1) {
// bucket no file
if (files.length === 0) {
file = acceptedFiles[0];
// 1st 4 bytes
const blob = file.slice(0, 4);
// read 4 bytes
reader.readAsArrayBuffer(blob);

// later
reader.onloadend = evt => {
if (evt.target.readyState === FileReader.DONE) {
// event res to unit
const uint = new Uint8Array(evt.target.result);
// byte
let bytes = [];
// loop each unit
uint.forEach(byte => {
bytes.push(byte.toString(16));
});
// hex
const hex = bytes.join('').toUpperCase();
const type = getMimetype(hex);

//test
console.log('hex', hex);
console.log('output', type);

// type is allowed
if (config.fileTypes.includes(type)) {
setFiles([...files, ...acceptedFiles]);
} else {
// type no good
setIsInvaildFileType(true);
}
}
};
} else {
// bucket has file already
setIsMaxFileNum(true);
}
} else {
// drop multiple files, no thinking of bucket
setIsMaxFileNum(true);
}
}
});

最佳答案

我还必须以类似的方式使用 react-dropzone 验证每个文件。
我的解决方法是 promise FileReader

1️⃣ This is the promisified version of "FileReader"
const isValidFile = file => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = evt => {
// other logic removed for brevity...

2️⃣ Your custom logic dictates, if the file is valid or not
if (config.fileTypes.includes(type)) {
resolve(true);
} else {
resolve(false);
}
};

3️⃣ Should there was an error, this file is not good.
reader.onerror = () => resolve(false)

4️⃣ Start the reading process.
const blob = file.slice(0, 4);
reader.readAsArrayBuffer(blob);
});
};

现在您可以在您提到的 for 循环中使用它。

const onDropAccepted = useCallback(acceptedFiles => {
// reset to default state
resetToDefaultState();

1️⃣ As `useCallback` accepts a non-async method,
Create a wrapped async method we can call here.
const processFiles = async () => {
if (config.isMultipleFiles === true) {
for (let i = 0; i < acceptedFiles.length; i++) {
const file = acceptedFiles[i];
2️⃣ Here is where we validate the file using the code above.
const isValid = await isValidFile(file);
if (!isValid) {
setIsInvaildFileType(true);
return;
}
}

3️⃣ At this point, all files are good.
setFiles([...files, ...acceptedFiles]);
} else {
// removed for brevity...
}
};

4️⃣ Let's fire up the process
processFiles();
});

关于javascript - 如何在循环内使用回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57908876/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com