Page MenuHomePhabricator

Transition all Wikimedia production code from $.Deferred to native Promises
Open, Needs TriagePublic


A polyfill that allows us to use native promises has been merged into core for nine months now.

This uses native micro-tasks under the hood instead of the (slower and more expensive) setTimeout ticks that jQuery uses.

We need to migrate all code from $.Deferred to native Promises. Expect lots of sub-tasks

Event Timeline


Migrating public-facing returns, specifically, might be best to hold off on. Deferred is compatible and consumable by standard Promise.all, then(), Promise, etc, so public-facing returns are okay to leave as-is until we're able to smoothly deprecate those with telemetry. Promise has fewer methods and has subtly different execution order.

Everything else is good to go, especially inline usage where we return Deferred to another thenable (Deferred or Promise) which are naturally casted as-needed and can be transparently swapped out. As well as more generally all internal use within an async code bases, such as in UI code.

It'd also be great to migrate all use of Deferred-specific done() and fail() to Promise-compatible then() and catch(). Perhaps we can use an ESLint rule for that? It'd be an easy and localised migration to swap those. Not fully blind find-and-replace, but at least no deprecation required. The one thing to look out for is that done() and fail() can sometimes run synchronously which might be relied upon within a code base. The most common scenario where I've run into that is unit tests that mock a Deferred and thus the test happens to complete asynchronously. Those will need to become async, but that's well-supported in QUnit nowdays.

We can also swap Promise.all for $.when (unless in a utility method that public-returns). In that case we also need to make sure es6-promise is added as dependency (unless we've enabled by default by then).

The no-deferred-done/no-deferred-fail rules probably don't have reason to be disabled, beyond deciding to perform local fixes later.

The wider no-deferred and no-jquery-when rules, we'll likely want to turn off in some directories or files and focus mainly on new code, and code that is actively worked on.

Change 656974 had a related patch set uploaded (by Krinkle; owner: Krinkle):
[mediawiki/core@master] mediawiki.special.upload: Use then() instead of done()

Change 656974 merged by jenkins-bot:
[mediawiki/core@master] mediawiki.special.upload: Use then() instead of done()