异步中的初始化减少
const handleFileChange = async (e) => {
const target = e?.target?.files;
const attachments = await Array.from(target).reduce(async (acum, file) => {
file.id = uniqid();
// const format = file.name.split('.').pop();
// if (IMAGE_FORMATS.includes(format)) {
setIsLoading(true);
if (file.type.startsWith('image/')) {
const response = await channel.sendImage(file);
file.src = response.file;
acum.images.push(file);
} else {
const response = await channel.sendFile(file);
file.src = response.file;
acum.files.push(file);
}
setIsLoading(false);
return acum;
}, Promise.resolve({ files: [], images: [] }));
setFilesList(prev => {
console.log('files', [...prev, ...attachments.files]);
return [...prev, ...attachments.files];
});
setImagesList(prev => {
console.log('images', [...prev, ...attachments.images]);
return [...prev, ...attachments.images];
});
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
async
函数返回承诺,这使得使用.Reduce()
时很难使用,因为您需要等待
您的累加器每次迭代获取您的数据。作为替代方案,您可以使用array.from()
(您可以将其视为使用.map()
在)
)。这里的想法是,该地图将使用sendimage
/sendfile
触发每个文件的多个异步调用。这些呼叫将在后台并行运行。我们从映射函数返回的价值将是一个承诺,它会在成功完成(一旦解决)成功完成时通知我们。此外,映射函数定义了承诺所解决的问题,在我们的情况下,它是带有src
属性的新对象:上面
filepromises
是一个承诺的数组(如<代码> async mapper函数隐含地返回承诺)。我们可以使用 等待我们解决的所有承诺。这比执行每个异步调用一个逐一呼叫要快,只有在我们等待之前的完成后才移动到下一个:最后,
fileObjects
是一个数组,它包含所有对象,都包含文件和图像。我们可以进行一次迭代,将此数组分为单独的数组,一个用于图像,一个用于文件:An
async
function returns Promise, which makes it difficult to work with when using.reduce()
as you would need toawait
your accumulator each iteration to get your data. As an alternative, you can create an array of Promises using the mapper function ofArray.from()
(which you can think of as using.map()
directly afterArray.from()
). The idea here is that the map will trigger multiple asynchronous calls for each file by usingsendImage
/sendFile
. These calls will run in parallel in the background. The value that we return from the mapping function will be a Promise that notifies us when the asynchronous call has successfully completed (once it resolves). Moreover, the mapping function defines what the promise resolves with, in our case that is the new object with thesrc
property:Above
filePromises
is an array of Promises (as theasync
mapper function returns a Promise implicitly). We can usePromise.all()
to wait for all of our Promises to resolve. This is faster than performing each asynchronous call one by one and only moving to the next once we've waited for the previous to complete:Lastly,
fileObjects
is an array that contains all objects, both files and images. We can do one iteration to partition this array into seperate arrays, one for images, and one for files:减少并不是真正的必要
在这一点上,
The reduce is not really necessary at this point:
Here is a solution with a
map
to transform the elements in promises and thenPromise.all
to wait for the exectution