【发布时间】:2021-12-15 18:26:28
【问题描述】:
目标:等待来自虚假服务器响应的自定义建议。
问题:我无法理解如何告诉 Monaco 编辑器完成项提供者等待异步建议。
游乐场示例:
- Go to playground
- 粘贴以下代码
console.log("1. Instantiate a standalone code editor");
const language = "json"
const content = `{\n\t\"dependencies\": {\n\t\t\n\t}\n}\n`
const options = {
value: content,
language: language,
tabSize: 2
}
const standaloneCodeEditor = monaco.editor.create(document.getElementById("container"), options);
const sce = standaloneCodeEditor;
console.log("2. Declare function to provide a completion items")
function provideCompletionItems(model, position) {
console.log("Invoking function 'provideCompletionItems'")
var textUntilPosition = model.getValueInRange({ startLineNumber: 1, startColumn: 1, endLineNumber: position.lineNumber, endColumn: position.column });
console.log("textUntilPosition:", textUntilPosition)
var match = textUntilPosition.match(/"dependencies"\s*:\s*\{\s*("[^"]*"\s*:\s*"[^"]*"\s*,\s*)*([^"]*)?$/);
console.log("match:", match)
if (!match) {
return { suggestions: [] };
}
var word = model.getWordUntilPosition(position);
console.log("word:", word)
var range = {
startLineNumber: position.lineNumber,
endLineNumber: position.lineNumber,
startColumn: word.startColumn,
endColumn: word.endColumn
};
console.log("range:", range)
const mock_serverResponse = [
{
label: '"lodash"',
kind: monaco.languages.CompletionItemKind.Function,
documentation: "The Lodash library exported as Node.js modules.",
insertText: '"lodash": "*"',
range: range
},
{
label: '"lodash111"',
kind: monaco.languages.CompletionItemKind.Function,
documentation: "The Lodash111 library exported as Node.js modules.",
insertText: '"lodash111": "*"',
range: range
},
{
label: '"express"',
kind: monaco.languages.CompletionItemKind.Function,
documentation: "Fast, unopinionated, minimalist web framework",
insertText: '"express": "*"',
range: range
},
{
label: '"mkdirp"',
kind: monaco.languages.CompletionItemKind.Function,
documentation: "Recursively mkdir, like <code>mkdir -p</code>",
insertText: '"mkdirp": "*"',
range: range
},
{
label: '"my-third-party-library"',
kind: monaco.languages.CompletionItemKind.Function,
documentation: "Describe your library here",
insertText: '"${1:my-third-party-library}": "${2:1.2.3}"',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
range: range
}
]
let myCustomSuggestions = [];
console.log("myCustomSuggestions:",myCustomSuggestions)
setTimeout(() => {
const myPromise = Promise.resolve(mock_serverResponse)
console.log("myPromise:",myPromise)
myPromise
.then(response => {
console.log("response:", response)
response.forEach(e => myCustomSuggestions.push(e))
console.log("myCustomSuggestions:",myCustomSuggestions)
return {
suggestions: myCustomSuggestions
}
})
.catch(err => console.error(err))
}, 2000)
}
console.log("3. Register completion items provider")
const completionItemProvider = monaco.languages.registerCompletionItemProvider(language, {
provideCompletionItems: () => provideCompletionItems(sce.getModel(), sce.getPosition())
});
- 显示 Web 开发者控制台(查看日志消息)
- 运行程序
- 在括号中输入单词 lodash
- 查看网络开发者控制台
- 请注意,没有显示任何建议
【问题讨论】:
-
为什么要等待建议?它会阻止你的用户界面。相反,使用承诺返回建议的方法是正确的方法。如果这需要更长的时间,摩纳哥将显示“正在加载...”弹出窗口。
-
我想等待建议,因为在真正的应用程序中,不是这个简单的例子,建议是从服务器给出的......前端接受一个字符串并调用一个 API 端点 - 服务器返回一个建议列表用户可以使用它在编辑器中完成编辑。
-
我想在 monaco 编辑器建议面板上看到“正在加载...” - 你能修改我的简单示例来告诉我如何获得它吗?
-
在评论中很难做到。试试自己,更改
provideCompletionItems函数。删除现有的返回调用并改为返回:return new Promise((resolve, reject) => {});然后运行示例并使用 ctrl+空格触发代码完成。您将看到“正在加载...”弹出窗口,因为承诺永远不会被解决。
标签: javascript asynchronous promise monaco-editor