Typescript 如何在vscode扩展名中实现“保存到文件”检查覆盖?
我必须在VisualStudio代码扩展中实现一个非常典型的编程模式:将某些内容保存到文件中,但在执行此操作之前检查目标文件是否存在,如果存在,请询问用户是否可以覆盖它 通常我会打开一个文件保存对话框,要求用户给我一个文件名,这个对话框会进行所有必要的检查,并在必要时得到用户的确认。然而,在vscode中,我们没有一个文件保存对话框。所以我正试图用我们有限的手段来实现这一点。幸运的是,几周前在消息对话框中添加了一个新的选项参数,使它们成为模态。但不知怎么的,我没能把握好时机。这是我的密码:Typescript 如何在vscode扩展名中实现“保存到文件”检查覆盖?,typescript,visual-studio-code,vscode-extensions,Typescript,Visual Studio Code,Vscode Extensions,我必须在VisualStudio代码扩展中实现一个非常典型的编程模式:将某些内容保存到文件中,但在执行此操作之前检查目标文件是否存在,如果存在,请询问用户是否可以覆盖它 通常我会打开一个文件保存对话框,要求用户给我一个文件名,这个对话框会进行所有必要的检查,并在必要时得到用户的确认。然而,在vscode中,我们没有一个文件保存对话框。所以我正试图用我们有限的手段来实现这一点。幸运的是,几周前在消息对话框中添加了一个新的选项参数,使它们成为模态。但不知怎么的,我没能把握好时机。这是我的密码:
window.showInputBox({
placeHolder: "<Enter full file name here>",
prompt: "Enter the name to an html file to save the diagram\n" }
).then((value: string) => {
if (value) {
let canWrite = true;
if (fs.existsSync(value)) {
canWrite = false;
window.showWarningMessage("The specified file exists already", { modal: true }, ...[ "Overwrite" ]).then((action: string) => {
if (action === "Overwrite") {
canWrite = true;
}
});
}
if (canWrite) {
var stream = fs.createWriteStream(value, { encoding: "utf-8", autoClose: true });
stream.on("error", function (error: any) {
window.showErrorMessage("Could not write to file '" + value + "'. " + error);
});
stream.once('open', function (fd) {
stream.write(text);
stream.end();
window.showInformationMessage("Diagram successfully written to file '" + value + "'.");
});
}
}
})
问题在于,对window.showWarningMessage的调用是非阻塞的,这意味着当已经执行if canWrite之后,对话框本身是模态的,打开代码。这不是一个大问题,因为此时canWrite为false,但是,一旦showWarningMessage thenable返回,则从showInputBox返回的外部thenable中不再执行任何代码,即if canWrite不会像我预期的那样再次执行。是不可能嵌套2个表,还是我做错了什么
经验丰富的typescript/vscode开发人员如何完成此任务?showWarningMessage无法按您的需要显示,您无法嵌套它。相反,您必须创建自己的Thenable方法,这需要一些重构
其主要思想是,您的储蓄必须返回一个承诺,并且它将在需要时控制showWarningMessage返回
function saveDiagram(text, filename): Promise<string | boolean> {
return new Promise((resolve, reject) => {
if (fs.existsSync(filename)) {
vscode.window.showWarningMessage("The specified file exists already", { modal: true }, ...[ "Overwrite" ]).then((action: string) => {
if (action === "Overwrite") {
resolve(filename);
} else {
resolve(false);
}
});
} else {
resolve(filename);
}
});
}
现在,您的扩展代码将采用thenable方法,正如您所期望的:
vscode.window.showInputBox({
placeHolder: "<Enter full file name here>",
prompt: "Enter the name to an html file to save the diagram\n" }
).then((value: string) => {
if (value) {
saveDiagram(text, value)
.then((filename) => {
if (filename) {
writeDiagramOnDisk(text, filename)
}
});
}
})
你的解决方案很有意义,我将来可能会用到。现在,我只需将我的保存代码移动到一个单独的函数,并直接调用它,或者在我找到一个现有文件并且用户同意覆盖它时调用它。
vscode.window.showInputBox({
placeHolder: "<Enter full file name here>",
prompt: "Enter the name to an html file to save the diagram\n" }
).then((value: string) => {
if (value) {
saveDiagram(text, value)
.then((filename) => {
if (filename) {
writeDiagramOnDisk(text, filename)
}
});
}
})