Repository navigation
Support promises #418
Description
Activity
+1
+1
+1
+1
On Aug 3, 2014 12:41 PM, "Wilson Júnior" notifications@github.com wrote:+1
—
Reply to this email directly or view it on GitHub
#418 (comment).This might be of interest to folks - talk on InfoQ about large nodejs project at kixeye where Paul Hill discusses why they liked Promises - http://www.infoq.com/presentations/kixeye-rest-api. While there is a ton of useful info in this talk, he specifically discusses Promises (they used Bluebird) starting at about 21:50. Besides the syntactic sugar/readability, he highlights how there is an "implicit try-catch" that allows centralizing error handling/logging. He also shows a code snippet (25:51) for how they did this that might be a useful pattern to consider including in the docs at some point, if possible.
Thank you all for the input. We're building a list of roadmap items at https://github.com/strongloop/loopback/wiki/Roadmap-brainstorming. 'Promise' is on the list too. Maybe we should move it to a gist so that community ideas can be accepted via PRs.
I've actually been using something similar...after
boot(app), insert:Promise = require 'bluebird' bbutil = require 'bluebird/js/main/util' for model, p of app.models Promise.promisifyAll p, filter: (name, func, target) -> return bbutil.isIdentifier(name) && !bbutil.isClass(func) && name.charAt(0) isnt '_' && name.indexOf('Async') is -1 && name isnt 'app'...pardon my coffeescript :)
This will promisify all the app's models at once. I have a couple more items in my filter to exclude attributes we don't need to promisify, but it basically works the same.
The main problem is that you can't use the promises in a boot script or model init script, but I think @coodoo takes care of that with his solution above (thanks!). You can use @coodoo's method for complex models, and then use the app.models loop to take care of the rest (it's ok to run
promisifyAll()twice on the same object with this filter.The other problem I've found is that it doesn't work for the model relations. For example:
user.posts.createAsync(...)will fail...I'm not sure how to go about promisifying those "virtual selectors"
I'm not sure how or where they are defined or attached...I was able to pause in the debugger and drill down a bit, but I'm still confused. There's some sort of convention for defining these methods that I'm not familiar with.
I'm looking at a user instance in the debugger...I'll try to asciify it :
user | ModelConstructor | __cachedRelations: Object | __dataSource: Object | |__data: Object | | email: "joe@schmoe.com" | | id: ObjectId | | ... | ... | |__proto__: ModelConstructor | | __count__accessTokens: function (cb) { | | __create__accessTokens: function () { | | __delete__accessTokens: function () { | | ...So if I understand this at all, it seems that anytime I access a property or method of a model instance, there's some javascript magic going on...
user.idgets translated touser.__data.id,user.accessTokens.count()callsuser.__count__accessTokens(), etc.I saw similarly named methods in the lb-services.js file generated for angularjs...
...What is this magic and how does it work? :)
The methods for relations are added to the model as properties with getters. For example, user.accessTokens will return a function bound to the user instance. The function itself also has other methods such as ‘create’, ‘count’, and ‘delete’. Please note the ____accessTokens methods are added to the User.prototype for legacy remoting purposes. These methods will probably be removed from the model prototype in the future.
Thanks,
Raymond Feng
Co-Founder and Architect @ StrongLoop, Inc.StrongLoop http://strongloop.com/ makes it easy to develop APIs http://strongloop.com/mobile-application-development/loopback/ in Node, plus get DevOps capabilities http://strongloop.com/node-js-performance/strongops/ like monitoring, debugging and clustering.
On Nov 18, 2014, at 3:58 PM, Partap Davis notifications@github.com wrote:
I was able to pause in the debugger and drill down a bit, but I'm still confused. There's some sort of convention for defining these methods that I'm not familiar with.
I'm looking at a user instance in the debugger...I'll try to asciify it :
user
| ModelConstructor
| cachedRelations: Object
| __dataSource: Object
| |__data: Object
| | email: "joe@schmoe.com"
| | id: ObjectId
| | ...
| ...
| |__proto: ModelConstructor
| | __count__accessTokens: function (cb) {
| | __create__accessTokens: function () {
| | __delete__accessTokens: function () {
| | ...
So if I understand this at all, it seems that anytime I access a property or method of a model instance, there's some javascript magic going on...user.id gets translated to user.__data.id, user.accessTokens.count() calls user.__count__accessTokens(), etc.I saw similarly named methods in the lb-services.js file generated for angularjs...
...What is this magic and how does it work? :)
—
Reply to this email directly or view it on GitHub #418 (comment).100 remaining items
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
@kjdelisle @raymondfeng I think we may need to address this issue as part of our work on LoopBackNext. At least the parts in juggler (e.g. scope methods), because we are reusing juggler in LoopBackNext so far.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been closed due to continued inactivity. Thank you for your understanding. If you believe this to be in error, please contact one of the code owners, listed in the
CODEOWNERSfile at the top-level of this repository.This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been closed due to continued inactivity. Thank you for your understanding. If you believe this to be in error, please contact one of the code owners, listed in the
CODEOWNERSfile at the top-level of this repository.
LoopBack should provide Promise-enabled API out of the box. The plan is to use the approach outlined in nodejs/node#173.
Tasks
automigrate,autoupdate,discover*, etc.app.listen@promiseannotation Support @promise annotation strong-docs#63@promiseattributeBelow is the original proposal from @coodoo.
I've been playing around with bluebird's promisifyAll() for a while, ended up I found it just take a couple of line to wrap the model and make it become async-compatible.
See code below:
Once the model is wrapped, we can use Promise syntax instead of callbacks:
Ain't that lovely? :)
Of course it would be even better if all those happened higher up in the chain and become default.
Thought?