Avoid native promises when importing modules#52412
Conversation
alexdima
left a comment
There was a problem hiding this comment.
I personally find the usage of an utility function to decrease code readability.
AFAICT, the following two snippets produce the same result:
const r1 = TPromise.wrap(import('vscode-textmate'));
const r2 = winJSRequire<typeof import('vscode-textmate')>('vscode-textmate');AFAICT, they both return correctly an instance of a WinJS Promise:
That is what I was using before in TMSyntax.ts. I would suggest to go with the TPromise.wrap syntax and to write a TSLint rule that looks for usages of import and reminds us that we should use TPromise.wrap around them.
Well, in the one case a native promise is created and in the other not, so even though both might produce the same result, your solution still mixes native promises and WinJS promises. I can see if |
|
@alexandrudima with
private doMoveItemToTrash(resource: uri): TPromise<void> {
const absolutePath = resource.fsPath;
return TPromise.wrap(import('electron')).then(electron => {
const result = electron.shell.moveItemToTrash(absolutePath);
if (!result) {
return TPromise.wrapError(new Error(isWindows ? nls.localize('binFailed', "Failed to move '{0}' to the recycle bin", paths.basename(absolutePath)) : nls.localize('trashFailed', "Failed to move '{0}' to the trash", paths.basename(absolutePath))));
}
this._onAfterOperation.fire(new FileOperationEvent(resource, FileOperation.DELETE));
return void 0;
});
}This does not happen with my proposed solution that avoids mixing native promises with WinJS promises where this can happen if the native promise resolves directly (the |
|
I can reproduce and here is a reduction: Refinement 1 let p1 = TPromise.wrap<number>(new Promise<number>(function(c, e) { c(1); }));
Promise.all([p1]);
// ==> Uncaught TypeError: this._state.then is not a functionRefinement 2: drop
|
|
The PR #49034 from Christof actually fixes this and IMHO we should take that, as winjs is broken unrelated to native promises --- se refinement 3. The root cause is that winjs overrides a promise's |
|
@chrmarti any reason you did not push your solution forward? |

We have seen issues when mixing native promises and WinJS promises in the past (e.g. the famous
this._state.then is not a function#49177).It is very easy to mix native promises and WinJS promises when using async imports like so:
return TPromise.timeout(0).then(() => import("something"));To prevent this from happening this PR introduces a
winJSRequire()method that is not using native promises at all, but WinJS directly.@Microsoft/vscode since it touches lots of areas and raising awareness
@jrieken and @alexandrudima to review if that makes sense to you
Unfortunately I did not find a way to have the import type flow through in the method so the usage of this method unfortunately has to repeat the import value twice.