javascript 如何显示具有承诺并发的进度通知

oknwwptz  于 2022-12-10  发布在  Java
关注(0)|答案(1)|浏览(169)

我正在使用TypeScript开发VS代码扩展,需要为工作区中的每个文件夹调用一些并发子进程,并弹出可见的进度通知。每个新的子进程可能需要几秒钟才能完成。
从child_process调用的Angular 来看,我的方法似乎工作得很好,但是在所有命令完成之前,进度条就消失了。
下面是我一直在使用的代码的一个示例。注意,我对async函数和Array.map一起使用的理解是,它将导致每个await同时运行。希望我的理解是正确的。

  1. export async function doStuffCmdHandler(channel: vscode.OutputChannel, context: vscode.ExtensionContext): Promise<void> {
  2. return vscode.window.withProgress({
  3. title: "Doing Stuff...",
  4. location: vscode.ProgressLocation.Notification,
  5. }, async (progress) => {
  6. if (vscode.workspace.workspaceFolders === undefined) {
  7. throw Error("Command must be ran from within a VS Code Workspace");
  8. } else {
  9. channel.clear();
  10. vscode.workspace.workspaceFolders.map(async (folder) => {
  11. try {
  12. // executeCommand() is a wrapper around child_process.exec which returns Promise<string>
  13. let results = await executeCommand(folder.uri.path);
  14. channel.show();
  15. channel.append(results);
  16. } catch (err) {
  17. channel.show();
  18. channel.append(`Error processing ${folder.uri.path}:\n\n`);
  19. channel.append(`${(err as Error).message}\n\n`);
  20. }
  21. });
  22. }
  23. }
  24. );
  25. }

如果我用一个常规的for循环顺序调用我的子进程(如下面的代码片段所示),那么我就不会有任何进度条问题。但是,我更喜欢同时调用这些进程:

  1. channel.clear();
  2. for (var folder of vscode.workspace.workspaceFolders) {
  3. try {
  4. // executeCommand() is a wrapper around child_process.exec which returns Promise<string>
  5. let results = await executeCommand(folder.uri.path);
  6. channel.show();
  7. channel.append(results);
  8. } catch (err) {
  9. channel.show();
  10. channel.append(`Error processing ${folder.uri.path}:\n\n`);
  11. channel.append(`${(err as Error).message}\n\n`);
  12. }
  13. };
xdnvmnnf

xdnvmnnf1#

在你的代码中任何地方都没有使用进度...而且你也没有遵循承诺的执行,所以你的函数在承诺结束之前就结束了。

  1. export async function doStuffCmdHandler(channel: vscode.OutputChannel, context: vscode.ExtensionContext): Promise<void> {
  2. return vscode.window.withProgress({
  3. title: "Doing Stuff...",
  4. location: vscode.ProgressLocation.Notification,
  5. }, async (progress) => {
  6. if (vscode.workspace.workspaceFolders === undefined) {
  7. throw Error("Command must be ran from within a VS Code Workspace");
  8. } else {
  9. channel.clear();
  10. const total = vscode.workspace.workspaceFolders.length;
  11. let done = 0;
  12. // Return a promise that will end once all promises have finished.
  13. return Promise.all(vscode.workspace.workspaceFolders.map(async (folder) => {
  14. try {
  15. // executeCommand() is a wrapper around child_process.exec which returns Promise<string>
  16. let results = await executeCommand(folder.uri.path);
  17. channel.show();
  18. channel.append(results);
  19. // Report something, reporting done vs total
  20. progress.report(++done+"/"+total);
  21. } catch (err) {
  22. channel.show();
  23. channel.append(`Error processing ${folder.uri.path}:\n\n`);
  24. channel.append(`${(err as Error).message}\n\n`);
  25. }
  26. }));
  27. }
  28. }
  29. );
  30. }
展开查看全部

相关问题