VS Code扩展开发:Promise并发下进度通知异常问题排查
问题原因
你用Array.map结合async函数时进度条提前消失的核心原因是:map会生成一个Promise数组,但你没有等待这些Promise全部完成。withProgress的回调函数在执行完map后就直接结束了,VS Code会认为任务已经完成,因此提前关闭进度通知。而顺序for循环里的await会逐个等待任务完成,回调函数会一直阻塞到所有任务结束,所以进度条显示正常。
解决方案
要实现并发调用同时保持进度条正常显示,需要用Promise.all等待所有异步任务完成,同时可以添加进度更新逻辑提升用户体验。
修改后的代码如下:
export async function doStuffCmdHandler(channel: vscode.OutputChannel, context: vscode.ExtensionContext): Promise<void> { return vscode.window.withProgress({ title: "Doing Stuff...", location: vscode.ProgressLocation.Notification, }, async (progress) => { const workspaceFolders = vscode.workspace.workspaceFolders; if (!workspaceFolders) { throw new Error("Command must be run from within a VS Code Workspace"); } channel.clear(); const totalFolders = workspaceFolders.length; let completedCount = 0; // 生成所有并发任务的Promise数组 const tasks = workspaceFolders.map(async (folder) => { try { const results = await executeCommand(folder.uri.path); channel.show(); channel.append(results); } catch (err) { channel.show(); channel.append(`Error processing ${folder.uri.path}:\n\n`); channel.append(`${(err as Error).message}\n\n`); } finally { // 无论任务成败,都更新进度 completedCount++; progress.report({ increment: 100 / totalFolders, message: `${completedCount}/${totalFolders} folders processed` }); } }); // 等待所有并发任务完成 await Promise.all(tasks); } ); }
关键修改说明
- 用
Promise.all等待所有任务:将map生成的Promise数组传入Promise.all并await,确保withProgress的回调函数会阻塞到所有异步任务结束,进度条才会消失。 - 添加进度实时更新:通过
progress.report在每个任务完成后更新进度条百分比和提示信息,让用户直观看到处理进度。 finally块保证进度更新:无论任务成功还是失败,都会执行进度更新逻辑,避免因个别任务报错导致进度卡住。
内容的提问来源于stack exchange,提问作者user16039166
相关产品推荐
相关产品推荐

