-
Notifications
You must be signed in to change notification settings - Fork 37.4k
Avoid native promises when importing modules #52412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
jrieken
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 as discussed
alexdima
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.