-
-
Notifications
You must be signed in to change notification settings - Fork 11
Description
I'd like to have a one-to-one correspondence between the text I send to the Textlint worker and the lint result I receive from the Textlint worker.
However, the order I received results from the Textlint worker can differ from the one I posted texts to the worker probably because kernel.lintText is async. Ref:
editor/packages/@textlint/script-compiler/src/CodeGenerator/worker-codegen.ts
Lines 125 to 136 in b32d016
| return kernel.lintText(data.text, { | |
| rules: rules, | |
| filterRules: config.filterRules, | |
| plugins: config.plugins, | |
| filePath: "/path/to/README" + data.ext, | |
| ext: data.ext, | |
| }).then(result => { | |
| return self.postMessage({ | |
| command: "lint:result", | |
| result | |
| }); | |
| }); |
So relying on message reception order can cause a race condition. Pseudocode:
worker.addEventListener("message", (event) => {
// lint result of text#2 comes first
// lint result of text#1 comes next
})
worker.postMessage({
command: "lint",
text: "text#1 very long text that takes a long time to lint",
ext: ".txt"
})
worker.postMessage({
command: "lint",
text: "text#2 short text; lint finishes quickly",
ext: ".txt"
})More higher-level example:
editor/packages/textchecker-element/index.ts
Lines 41 to 63 in b32d016
| const lintText: LintEngineAPI["lintText"] = async ({ text }: { text: string }): Promise<TextlintResult[]> => { | |
| updateStatus("linting..."); | |
| return new Promise((resolve, _reject) => { | |
| worker.addEventListener( | |
| "message", | |
| function (event) { | |
| const data: TextlintWorkerCommandResponse = event.data; | |
| if (data.command === "lint:result") { | |
| resolve([data.result]); | |
| } | |
| updateStatus("linted"); | |
| }, | |
| { | |
| once: true | |
| } | |
| ); | |
| return worker.postMessage({ | |
| command: "lint", | |
| text, | |
| ext: ext | |
| } as TextlintWorkerCommandLint); | |
| }); | |
| }; |
const texts = ["text#1 very long text that takes a long time to lint", "text#2 short text; lint finishes quickly"]
const results = await Promise.all(texts => lintText({ text }))
// [<lint result of text#2>, <lint result of text#2>]
// lint result of text#1 goes awaySome Web Worker libraries use IDs in messages. I think it can be one of the ideas to solve this problem.
For example, comlink:
For another example, minlink: