Skip to content

Commit f9a5ff5

Browse files
committed
Updates
1 parent 714811c commit f9a5ff5

1 file changed

Lines changed: 18 additions & 19 deletions

File tree

text/1220-deprecate-rsvp.md

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,22 @@ project-link:
1616

1717
## Summary
1818

19-
Deprecate `Ember.RSVP` and the `rsvp` module bundled with `ember-source`.
19+
Deprecate the `rsvp` module bundled with `ember-source`.
2020

2121
Native `Promise` has been in every browser and node version we support for a long time now, and covers nearly everything RSVP does.
2222
[`ember-data` already did this](https://github.com/emberjs/rfcs/pull/796) back in 2022.
2323

24-
The [`rsvp` package on npm](https://www.npmjs.com/package/rsvp) isn't going anywhere -- if folks want to keep using it, they can depend on it directly.
24+
The [`rsvp` package on npm](https://www.npmjs.com/package/rsvp) itself is unaffected by this deprecation, but we recommend migrating to native `Promise` rather than adding a direct dependency on `rsvp`.
2525

2626
## Motivation
2727

28-
RSVP was created before `Promise` existed in any browser. It was needed then. It is not needed now.
28+
RSVP is Ember's Promises/A+ implementation from before browsers had one, and native `Promise` has since made almost all of it redundant.
2929

3030
Deprecating it:
3131
- slims down our public API surface area to more of _what's needed_
3232
- removes bytes from every app (RSVP is bundled with `ember-source` whether you use it or not)
33-
- removes one of the remaining ties to the runloop -- `ember-source` configures RSVP to schedule promise resolution via backburner, which is a blocker for eventually removing the runloop
34-
- removes "another case to cover" for tooling, types, and teaching -- new folks should only ever learn native `Promise`
33+
- removes one of the remaining ties to the runloop (`ember-source` configures RSVP to schedule promise resolution via backburner, which blocks eventually removing the runloop)
34+
- removes "another case to cover" for tooling, types, and teaching. New folks should only ever have to learn native `Promise`
3535

3636
## Transition Path
3737

@@ -56,7 +56,7 @@ Most usage is a mechanical find-and-replace:
5656

5757
[^settled]: the result objects differ slightly: RSVP uses `{ state: 'fulfilled' }`, native uses `{ status: 'fulfilled' }`.
5858

59-
[^defer]: `{ promise, resolve, reject }` -- same shape as `RSVP.defer()`.
59+
[^defer]: returns `{ promise, resolve, reject }`, the same shape as `RSVP.defer()`.
6060

6161
`RSVP.hash` is the only utility without a native equivalent, and it's a one-liner:
6262

@@ -70,7 +70,7 @@ async function hash(obj) {
7070
}
7171
```
7272

73-
(or use an existing micro-library, such as the one behind [`WarpDrive`'s `getPromiseState`](https://docs.warp-drive.io), or write it inline -- two `await`s is often clearer than `hash` anyway)
73+
(or write it inline; two `await`s is often clearer than `hash` anyway)
7474

7575
<details><summary>example codemod-ish diff</summary>
7676

@@ -102,15 +102,14 @@ async function hash(obj) {
102102
In practice these are nearly indistinguishable (backburner has been microtask-based since ember-source@3.x), but:
103103

104104
- test code that relied on `await settled()` "seeing" pending RSVP chains should use [`@ember/test-waiters`](https://github.com/emberjs/ember-test-waiters) for any async that renders
105-
- code that relied on `RSVP.on('error')` for global error reporting should use the `unhandledrejection` event (or `Ember.onerror`, until [that, too, goes away](https://deprecations.emberjs.com/))
105+
- code that relied on `RSVP.on('error')` for global error reporting should use the `unhandledrejection` event
106106

107107
### Deprecation mechanics
108108

109-
- accessing `Ember.RSVP` issues a deprecation
110-
- `id: deprecate-rsvp`, `until: 7.0.0`
111-
- importing `'rsvp'` in an app or v1 addon where the module is provided by `ember-source` issues a build-time deprecation
112-
- apps / addons that install `rsvp` from npm themselves are unaffected -- the deprecation only covers the copy bundled with `ember-source`
113-
- `ember-source`'s internals (`ember-testing`, router promise handling) migrate to native promises -- not observable except via `instanceof RSVP.Promise` checks, which nobody should be doing
109+
- the `rsvp` module provided by `ember-source` issues a runtime deprecation (via the existing deprecation system, `deprecate` from `@ember/debug`) when any of its exports are used
110+
- `id: deprecate-rsvp`, `until: 8.0.0`
111+
- the deprecation only covers the copy bundled with `ember-source`. Installing `rsvp` from npm directly would silence it, but migrating to native `Promise` is the recommended path
112+
- `ember-source`'s internals (`ember-testing`, router promise handling) migrate to native promises. This is not observable, except via `instanceof RSVP.Promise` checks, which nobody should be doing
114113
- a lint rule should be added to `eslint-plugin-ember`'s recommended config flagging `rsvp` imports
115114

116115
### Deprecation guide
@@ -129,32 +128,32 @@ In practice these are nearly indistinguishable (backburner has been microtask-ba
129128
> await Promise.all(promises);
130129
> ```
131130
>
132-
> If you need RSVP-specific behavior, add `rsvp` to your own `package.json` -- the npm package is unaffected by this deprecation.
131+
> We recommend migrating to native `Promise` rather than adding a dependency on the `rsvp` npm package; everything RSVP provides has a native equivalent or a small inline replacement.
133132
134133
## How We Teach This
135134
136135
The guides and blueprints already use native promises and `async`/`await` everywhere.
137136
138137
Remaining work:
139138
- add the deprecation guide entry to https://deprecations.emberjs.com
140-
- mark `Ember.RSVP` / the `rsvp` module as deprecated in the API docs
139+
- mark the `rsvp` module as deprecated in the API docs
141140
142-
This is a _reduction_ in what we have to teach: there is no longer a "which Promise?" question.
141+
Overall, this reduces what we have to teach, since there is only one kind of promise left.
143142
144143
## Drawbacks
145144
146145
As with any deprecation, we introduce an upgrade cliff for addons that are updated infrequently, and consequently their consuming apps.
147146
148-
The mitigation here is unusually easy though: unlike most deprecations, the replacement (`Promise`) works in _every_ supported Ember version, so addons can migrate today with no `@embroider/macros` dance and no version-range narrowing. Addons that genuinely need RSVP can depend on it from npm directly, which also works across all versions.
147+
Unlike most deprecations, though, the replacement (`Promise`) works in every supported Ember version, so addons can migrate today without `@embroider/macros` and without narrowing their supported version range.
149148
150-
The main real cost is timing-sensitive test suites discovering they were implicitly depending on RSVP's runloop scheduling. `@ember/test-waiters` is the answer, and that migration is valuable independent of this RFC.
149+
The bigger cost is timing-sensitive test suites that implicitly depend on RSVP's runloop scheduling. Those need `@ember/test-waiters`, which they should be using regardless of this RFC.
151150
152151
## Alternatives
153152
154153
do nothing, the cost of bundling RSVP is:
155154
- bytes in every app, used or not
156155
- a permanent tie between promise resolution and the runloop
157-
- mental gymnastics for teaching ("use native promises, except this framework object you may encounter is a different kind of promise")
156+
- mental gymnastics for teaching ("use native promises, except this module the framework ships is a different kind of promise")
158157
- "another case to cover" for tooling and types
159158
160159
deprecate only the runloop integration, keep re-exporting `rsvp`

0 commit comments

Comments
 (0)