修复素材导出并发竞态
使用同步 ref 互斥量保护集合导出和单选导出 在导出 finally 中释放互斥量并保留 state 作为忙碌 UI 新增同一事件循环连续导出的回归测试
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import JSZip from 'jszip';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useCallback, useRef, useState } from 'react';
|
||||
|
||||
import type {
|
||||
CanvasAssetExportImage,
|
||||
@@ -273,6 +273,7 @@ export function useImageCanvasAssetExportWorkflow({
|
||||
const [assetExportStatus, setAssetExportStatus] =
|
||||
useState<AssetExportStatus | null>(null);
|
||||
const [isExportingAssets, setIsExportingAssets] = useState(false);
|
||||
const isExportingAssetsRef = useRef(false);
|
||||
|
||||
const exportLayerImage = useCallback(
|
||||
async (
|
||||
@@ -347,7 +348,7 @@ export function useImageCanvasAssetExportWorkflow({
|
||||
emptyMessage: string;
|
||||
successMessage: string;
|
||||
}) => {
|
||||
if (isExportingAssets) {
|
||||
if (isExportingAssetsRef.current) {
|
||||
return;
|
||||
}
|
||||
const exportableLayers = targetLayers
|
||||
@@ -361,6 +362,7 @@ export function useImageCanvasAssetExportWorkflow({
|
||||
return;
|
||||
}
|
||||
|
||||
isExportingAssetsRef.current = true;
|
||||
setIsExportingAssets(true);
|
||||
setAssetExportStatus(null);
|
||||
|
||||
@@ -609,10 +611,11 @@ export function useImageCanvasAssetExportWorkflow({
|
||||
message: '素材导出失败',
|
||||
});
|
||||
} finally {
|
||||
isExportingAssetsRef.current = false;
|
||||
setIsExportingAssets(false);
|
||||
}
|
||||
},
|
||||
[isExportingAssets, projectTitle],
|
||||
[projectTitle],
|
||||
);
|
||||
|
||||
const exportCanvasAssets = useCallback(
|
||||
@@ -628,7 +631,7 @@ export function useImageCanvasAssetExportWorkflow({
|
||||
|
||||
const exportSelectedAssets = useCallback(
|
||||
async (selectedLayers: CanvasLayer[]) => {
|
||||
if (isExportingAssets) {
|
||||
if (isExportingAssetsRef.current) {
|
||||
return;
|
||||
}
|
||||
const exportableLayers = selectedLayers.filter(
|
||||
@@ -642,11 +645,13 @@ export function useImageCanvasAssetExportWorkflow({
|
||||
return;
|
||||
}
|
||||
if (exportableLayers.length === 1) {
|
||||
isExportingAssetsRef.current = true;
|
||||
setIsExportingAssets(true);
|
||||
setAssetExportStatus(null);
|
||||
try {
|
||||
await exportLayerImage(exportableLayers[0] ?? null);
|
||||
} finally {
|
||||
isExportingAssetsRef.current = false;
|
||||
setIsExportingAssets(false);
|
||||
}
|
||||
return;
|
||||
@@ -658,7 +663,7 @@ export function useImageCanvasAssetExportWorkflow({
|
||||
successMessage: '选中素材已导出',
|
||||
});
|
||||
},
|
||||
[exportAssetCollection, exportLayerImage, isExportingAssets],
|
||||
[exportAssetCollection, exportLayerImage],
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user