2017-04-18 59 views
0

我必須在Visual Studio代碼擴展中實現一個非常典型的編程模式:將某些東西保存到文件中,但在檢查之前檢查目標文件是否存在,並詢問用戶是否可以覆蓋它,如果存在。如何在vscode擴展中實現save-to-file-check-overwrite?

通常我會打開一個文件保存對話框,要求用戶給我一個文件名,如果需要,這個對話框會做所有必要的檢查並得到用戶確認。但是,在vscode中我們沒有文件保存對話框(但是有a feature request)。所以我試圖用我們那裏有限的手段來實現這一點。幸運的是,幾個星期前,一個新的選項參數被添加到消息對話框中,以使它們成爲模態。但不知何故,我無法獲得正確的時機。這裏是我的代碼:

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可接受的返回沒有代碼在外層可執行(從showInputBox),即if (canWrite)不再執行(正如我所期望的)。是不可能嵌套兩個可敬的或我做了什麼錯了?

有經驗的typecript/vscode發展者如何處理這項任務?

回答

0

showWarningMessage不是你所需要的,你不能嵌套它。相反,你必須創建你自己的Thenable方法,這需要一些重構。

主要的想法是,你保存必須返回一個Promise,它會控制showWarningMessage回報(需要時)

​​

而且提取物對磁盤您寫作圖表作爲一個新的功能,被稱爲後者:

function writeDiagramOnDisk(text, filename) { 
    var stream = fs.createWriteStream(filename, { encoding: "utf-8", autoClose: true }); 
    stream.on("error", function (error: any) { 
     vscode.window.showErrorMessage("Could not write to file '" + filename + "'. " + error); 
    }); 
    stream.once('open', function (fd) { 
     stream.write(text); 
     stream.end(); 

     vscode.window.showInformationMessage("Diagram successfully written to file '" + 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) 
       } 
      }); 

    } 
}) 
+0

您的解決方案很有意義,我將來可能會使用它。現在,我只是將保存代碼移到一個單獨的函數中,直接調用或者一旦找到現有文件並且用戶同意覆蓋它。 –