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

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

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

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) => {
            if (vscode.workspace.workspaceFolders === undefined) {
                throw Error("Command must be ran from within a VS Code Workspace");
            } else {
                channel.clear();
                vscode.workspace.workspaceFolders.map(async (folder) => {
                    try {
                        // executeCommand() is a wrapper around child_process.exec which returns Promise<string>
                        let 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`);
                    }
                });
            }
        }
    );
}

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

channel.clear();
for (var folder of vscode.workspace.workspaceFolders) {
    try {
        // executeCommand() is a wrapper around child_process.exec which returns Promise<string>
        let 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`);
    }
};
xdnvmnnf

xdnvmnnf1#

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

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) => {
            if (vscode.workspace.workspaceFolders === undefined) {
                throw Error("Command must be ran from within a VS Code Workspace");
            } else {
                channel.clear();
                const total = vscode.workspace.workspaceFolders.length;
                let done = 0;
   // Return a promise that will end once all promises have finished.
                return Promise.all(vscode.workspace.workspaceFolders.map(async (folder) => {
                    try {
                        // executeCommand() is a wrapper around child_process.exec which returns Promise<string>
                        let results = await executeCommand(folder.uri.path);
                        channel.show();
                        channel.append(results);
                        // Report something, reporting  done vs total
                        progress.report(++done+"/"+total);
                    } catch (err) {
                        channel.show();
                        channel.append(`Error processing ${folder.uri.path}:\n\n`);
                        channel.append(`${(err as Error).message}\n\n`);
                    }
                }));
            }
        }
    );
}

相关问题