You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: text/1220-deprecate-rsvp.md
+18-19Lines changed: 18 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,22 +16,22 @@ project-link:
16
16
17
17
## Summary
18
18
19
-
Deprecate `Ember.RSVP` and the `rsvp` module bundled with `ember-source`.
19
+
Deprecate the `rsvp` module bundled with `ember-source`.
20
20
21
21
Native `Promise` has been in every browser and node version we support for a long time now, and covers nearly everything RSVP does.
22
22
[`ember-data` already did this](https://github.com/emberjs/rfcs/pull/796) back in 2022.
23
23
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`.
25
25
26
26
## Motivation
27
27
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.
29
29
30
30
Deprecating it:
31
31
- slims down our public API surface area to more of _what's needed_
32
32
- 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`
35
35
36
36
## Transition Path
37
37
@@ -56,7 +56,7 @@ Most usage is a mechanical find-and-replace:
56
56
57
57
[^settled]: the result objects differ slightly: RSVP uses `{ state: 'fulfilled' }`, native uses `{ status: 'fulfilled' }`.
58
58
59
-
[^defer]: `{ promise, resolve, reject }` -- same shape as `RSVP.defer()`.
59
+
[^defer]: returns `{ promise, resolve, reject }`, the same shape as `RSVP.defer()`.
60
60
61
61
`RSVP.hash` is the only utility without a native equivalent, and it's a one-liner:
62
62
@@ -70,7 +70,7 @@ async function hash(obj) {
70
70
}
71
71
```
72
72
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)
In practice these are nearly indistinguishable (backburner has been microtask-based since ember-source@3.x), but:
103
103
104
104
- 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
106
106
107
107
### Deprecation mechanics
108
108
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
114
113
- a lint rule should be added to `eslint-plugin-ember`'s recommended config flagging `rsvp` imports
115
114
116
115
### Deprecation guide
@@ -129,32 +128,32 @@ In practice these are nearly indistinguishable (backburner has been microtask-ba
129
128
>awaitPromise.all(promises);
130
129
>```
131
130
>
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.
133
132
134
133
## How We Teach This
135
134
136
135
The guides and blueprints already use native promises and `async`/`await` everywhere.
137
136
138
137
Remaining work:
139
138
- 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
141
140
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.
143
142
144
143
## Drawbacks
145
144
146
145
As with any deprecation, we introduce an upgrade cliff for addons that are updated infrequently, and consequently their consuming apps.
147
146
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.
149
148
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.
151
150
152
151
## Alternatives
153
152
154
153
do nothing, the cost of bundling RSVP is:
155
154
- bytes in every app, used or not
156
155
- 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")
158
157
- "another case to cover" for tooling and types
159
158
160
159
deprecate only the runloop integration, keep re-exporting `rsvp`
0 commit comments