ember-data + Promises
The Promise usage within ember-data needs some TLC.
I often find myself needing to tediously manage multiple events, just to know when a simple action, such as save, has completed. In addition, some of the async actions that return promises never reject. (find*)
I think we have a good foundation, but with some extra thought and work, we can make some drastic improvements.
DS.Model is a promise-entity that resolves when the record is loaded, or brought into existence. (find/create) All future saves/updates/commits function calls will not affect this "base promise-entity". Rather these functions will return new promises, that will resolve or reject the record based on the result of the functions intent.
resolve on load.
Top level api improvements/changes
find*: -> promise-entity
createRecord: -> promise-entity
commit: -> promise
save: -> promise
reload: -> promise
commit: -> promise
deleteRecord: -> promise
RecorArray -> promise will resolve when all its known children are resolved, adding/removing later will not be reflected. Goal #1 is initial load.
record = store.find(Record, 1) record.then(recordDidLoad, recordFailedToLoad); // ... record.save().then(didSave, failedToSave) record.update().then(didUpdate, failedToUpdate) record.deleteRecord().then(didDelete, failedToDelete) record.then(...) // error if record is deleted record.get('transaction').commit().then(didCommit, failedToCommit)
- Adapter should return promises from all its asynchronous functions
- For some revs, existing adapters using the non-promise API should be supported with deprecation warnings.
- Store's corresponding async calls into adapter, should be done with promises
- all promises must be a+ compliant (ideally RSVP)
- $.ajax can be used at the edges, but must be must be wrapped by RSVP.wrap
- jQuery promises have some inconsistencies, which makes mixing them with a+ promises a bad idea.
A point of concern:
Although promises are powerful, it is easy to accidentally allow them to eat important exceptions. This is bad. We may want some or all of the following:
- Ability to add a resolver for unhandled errors to a promise chain (would require changes to rsvp).
- A dev flag for noisy promises to log all non-propagated errors (or perhaps all errors).
- A hook in
DS.Store, for unhandled errors.
- [done] get RSVP#resolve merged in
- [in-progress + issues] get promises resolved with themselves
- [in-progress] get RSVP2 into ember
- [in-progress] get RSVP2 into ember-data
- assure existing promises actually reject and resolve when one expects them to. (find/create)
- async methods (save/reload/commit etc..) should return promises.
- store and adapters async communication should be done via promises.