I am developing a VS Code Extension using TypeScript and need to make some concurrent child-process calls for each folder in the workspace, with a visible progress notification popup. Each new child process will likely take a few seconds to complete.
My approach seems to work fine from the perspective of the child_process calls but the progress bar disappears before all the commands have completed.
Here is a sample of the code I have been working with. Note that my understanding of using an async
function with Array.map
is that it will result in each await
being ran concurrently. Hopefully I am correct with that.
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`);
}
});
}
}
);
}
If I make my child process calls sequentially with a regular for loop (as per the snippet below) then I don't have any progress bar issues. Howevever, I would prefer to make these calls concurrently:
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`);
}
};