-
Notifications
You must be signed in to change notification settings - Fork 29.5k
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
WinJS.Promise removal plan #53526
Comments
fyi @Microsoft/vscode we are down to 56 references to |
Progress is now 100% removed in |
WinJS.Promise#cancel is now removed in |
@Microsoft/vscode With the removal of ❗️ A word of caution: The timings of winjs-promises and native promises differ! A winjs-promise that is resolved synchronously will call its then-handler immediately (instead of waiting for the next tick). We have some unit tests that outline the differences. https://github.com/Microsoft/vscode/blob/3c2dbc17b84191950cd61b9c8d95776abdc672f6/src/vs/base/test/common/winjs.polyfill.promise.test.ts#L13-L39 Please keep this in mind when replacing winjs-promises with native promises. Also note that this is not only for constructor calls but also when calling |
The above behavior is an issue when using Monaco with Zone.js and Angular. ZoneAwarePromise's all function is as follows:
This implementation is relying on the microtask that's missing from the WinJS completed promise. As a result, calling ZoneAwarePromise.all([winJsPromise1, winJsPromise2]) will be resolved with the array [result2] instead of the expected [result1, result2]. Here's a Fiddle demonstrating the issue. I noticed the issue when using Monaco + Angular and setting error markers on the editor. The hover text rendered 'undefined' instead of my intended message text because of this line in HtmlContentRenderer -- @jrieken any suggestions for handling this? Is sync then-handler invocation a desired/necessary behavior? If so, I suppose we'll have to try and patch Zone.js |
Unfortunately not. I'd patch Zone.js or use native Promise.all instead |
Only Good news is that after the removal of progress and cancel the migration is simple. Whereever a winjs-promise is being returned a native-promise can and should be returned. Please invest some time to migrate your code:
When migrating think of the differences in the runtime behaviour! This affects promises that are synchronously resolved (via the constructor callback or via above utils) and that have a then-handler (all details here) // NATIVE promise behaviour
const promise = new Promise(resolve => {
// 1️⃣
resolve(null);
}).then(() => {
// 3️⃣
});
// 2️⃣
// WINJS promise behaviour
const promise = new WinJSPromise(resolve => {
// 1️⃣
resolve(null);
}).then(() => {
// 2️⃣
});
// 3️⃣ |
Makes me so glad to see WinJs -> native promises. I hope to see more async awaits in vscode in the future. |
We are heavy users of WinJS.Promise and that's not good. We started with the monaco-editor before native promises existed, so WinJS.Promises came in handy. However, times have changed, native promises are real and sticking with WinJS.Promises became a dead end. Time for change...
Migrating from WinJS.Promise to the native promises isn't a find/replace-job because of some incompatibilities, namely the runtime-behaviour and different APIs. In a first wave we want to focus on two elephants:
WinJS.Promise#cancel
with theCancellationToken
WinJS.Promise#then(_, _, onProgress)
with a different progress-storyWinJS.Promise#ctor
WinJS.Promise#as|wrap|wrapError|join
Replace WinJS.Promise.as with Promise.resolve #64597, Replace WinJS.Promise.join with Promise.all #64598, Replace WinJS.Promise.wrap with Promise.resolve #64596, Instantiate native promise instead of WinJS.Promise #62716In more detail
WinJS.Promise#cancel
Calling
winjsPromise.cancel()
does two things: (1) it calls a cancel-handler that you provide when constructing a winjs-promise and (2) it puts the promise in the rejected-state with a cancelled-error.The native promise doesn't support cancellation and it needs to be replaced it with our own solution. For extensions we already offer
CancellationTokenSource
andCancellationToken
and we want to adopt it for "internal" use too. It's important to know that a cancellation token is just a hint and that a consumer might ignore it and proceed as before. In contrast to the winjs-promise-behaviour that means you must not end-up in the rejection-handler but you might end-up in the success-handler. That's fine as long as you can handle it.Because all of our code is written (and tested) with the winjs-promise-behaviour in mind we have added a util that makes adoption easy:
CancelablePromise
andcreateCancelablePromise
. Checkout the initial commit to understand how to use it: https://github.com//Microsoft/vscode/commit/727c6f3537d732269db30cbb9efd496073351586. The contract is that callingcancel
puts the promise into the rejected-state using the well-known cancelled-error.onProgress
The
then
-function of winjs-promises can accept three callbacks and the latter is used for progress events. Those can fire multiple times during promise execution. Again, nothing the native promise supports and something we need to replace with our own code. There is PR in which this effort is tracked: #53487Differences in runtime behaviour
The winjs-promise shows different runtime behaviour then native promises and when switching to native promises you should be aware of that. In contract to native promises, a winjs-promise that is resolved in its executor-function calls its then-handlers immediately. Check with these tests that outline the differences: https://github.com/Microsoft/vscode/blob/11c5b9381b8d1db012055201d48cc4d37299afce/src/vs/base/test/common/winjs.polyfill.promise.test.ts#L36
The text was updated successfully, but these errors were encountered: