【问题标题】:How to implement a busy indicator in vscode?如何在 vscode 中实现繁忙的指标?
【发布时间】:2017-09-27 10:58:48
【问题描述】:

对于一个长时间运行的进程,我想在 Visual Studio Code 中显示一个繁忙的指示器。有类似 typescript 扩展使用的东西就足够了:

但是,使用正常的状态栏项目无法按预期工作。我什至无法在开始操作之前显示该项目,因为它似乎需要将控制权返回给 vscode。

我试过的是这样的:

...
busyIndicator = window.createStatusBarItem(StatusBarAlignment.Left, 1000);
busyIndicator.text = "##";
busyIndicator.show();

...

workspace.onDidSaveTextDocument((doc: TextDocument) => {
    if (doc.languageId === "antlr") {
        //busyIndicator.show();
        busyIndicator.text = "X";
        let tempPath = Utils.createTempFolder();
        let result = backend.generate(doc.fileName, { outputDir: tempPath, listeners: false, visitors: false });
        Utils.deleteFolderRecursive(tempPath);
        //busyIndicator.hide();
        busyIndicator.text = "Y";
    }
});

值 X 永远不会显示,并且在操作结束时出现 Y(如预期的那样)。如果连简单的文本更新都不起作用,我怎么能显示动画?

【问题讨论】:

标签: typescript visual-studio-code vscode-extensions


【解决方案1】:

我无法弄清楚何时添加了对在状态栏中使用 withProgress 的支持,但我今天可以执行以下操作。

我在添加对此的支持时发现的编辑,那是 2017 年 4 月。请参阅 vscode 发行说明here

 vscode.window.withProgress({
    location: vscode.ProgressLocation.Window,
    cancellable: false,
    title: 'Loading customers'
}, async (progress) => {
    
    progress.report({  increment: 0 });

    await Promise.resolve();

    progress.report({ increment: 100 });
});

在下图中查看它的实际效果

【讨论】:

    【解决方案2】:

    现在看到https://code.visualstudio.com/updates/v1_22#_show-long-running-operations-as-notifications-with-cancellation-support 不是状态栏而是通知。

    **

    将长时间运行的操作显示为带有取消的通知 支持

    **

    我们添加了一个新 API 以在通知中显示长时间运行的操作 具有可选取消支持的中心。展示的好处 这里长时间运行的操作是:多个操作可以报告 同时进步。您可以显示操作进度。用户 可以选择取消操作。

    致电window.withProgress 提供新的进度位置 ProgressLocation.Notification。将cancellable设置为true以显示 取消按钮并检查提供的取消 CancellationToken 在回调中。要显示进度,请利用 报告进度时增加值。请参阅进度示例 使用这个新 API 的扩展。

    【讨论】:

    • 很高兴看到这个补充,虽然它在我这样的情况下没有帮助,我没有进展报告。我需要一个不确定的进度指示器。应该为此创建一个 FR...
    【解决方案3】:

    没有类似于Tasks 所做的已发布 API(在状态栏中显示旋转)。但是查看 VSCode 源代码,特别是task.contributions.ts,您可以看到它结合了setIntervalEventEmitter 来处理进度状态栏更新

    Webpack Progress extension 是一个很好的例子,说明如何做到这一点。

    基本上,您必须创建希望更新状态栏的时间间隔。这里将是您的backend 进程监控:

    initializeWacher() {
        this.timer = setInterval(() => {
            this.progress++;
            fs.stat(tempPath, (err, state) => {
                if(err && err.code === "ENOENT") {
                    this.emit("progressFinish")
                } else {
                    this.emit("progressChange", this.percentage)
                }
            });        
        }, 300);
    }
    

    处理间隔发出的事件:

    watcher.initializeWacher();
    watcher.on("progressChange", (progress) => {
        progress.updateProgress(progress);
    });
    watcher.on("progressFinish", () => {
        progress.finishProgress();
        watcher.dispose();
    });
    

    并在事件发生时更新状态栏(旋转本身):

    private static progressChars: string = '|/-\\';
    ...
    updateProgress(percentage) {
        ...
        let index = percentage % BusyIndicatorItem.progressChars.length;
        let chars = BusyIndicatorItem.progressChars.charAt(index);
        busyIndicator.text = "Backend processing " + chars;
    }
    
    finishProgress() {
        this.statusBarItem.text = "Backend finished";
    }
    

    【讨论】:

    • 不完全是我想要的,但它让我走上了正确的道路。这里重要的是任务异步运行,否则它将阻塞主线程,因此不会发生更新。一旦我将它转换为返回一个承诺,事情就开始按预期进行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-31
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多