-
Notifications
You must be signed in to change notification settings - Fork 298
Promises API #80
Comments
I like promises, but I know some people get very angry if you tell them to move away from callbacks, so please lets not have big fight about it. Using bluebird it's very easy to expose a callback + promise api which I favor as it gives people the ability to use what they prefer. |
I agree that this doesn't need to be prioritized. If it works, let it stay as it is. |
Bluebird's promisifyAll works perfectly here. I only use this lib with promises, eg: https://github.com/nodesphere/nodesphere/blob/1479f40cef4824e3135a20f65889a8110d0fc042/lib/adaptor/ipfs.coffee#L26-L31 |
@dignifiedquire hah, people that get angry over programming things always amazes me. Anyways, callback+promises might be the way to go forward, if Bluebird makes that easy and is compatible with native Promise. @RichardLitt for sure, cosmetic change at most but still valuable one when you're building something bigger than just using @harlantwood Oh, didn't know about Bluebird's |
Bingo. Promises and Callbacks are the higher-level equivalent of semicolons and no semicolons. Best to avoid entirely if you're not doing a major refactor with new team. |
@RichardLitt Well, it being a cosmetic thing doesn't mean that you can ignore it completely. You want people to use a library? Make sure the API for using it is simple and up-to-date with the rest of the ecosystem. I didn't open up this issue to propose a change of this right now. But I'm sure the library would be more pleasant for people to use, if in the future, we can provide something like what @harlantwood suggested above. But please, is not the end of the world if it doesn't exists. |
I don't like promises very much, and using them doesn't usually make my life more pleasant. I don't care if promises are supported, as long as I get a callback api without having to wrap promises to not use them. |
As much as I love bluebird, I would not use it in this lib unless you have very strong reasons to use it instead of something that can be removed for native promises. Also see: https://github.com/HenrikJoreteg/native-promisify-if-present |
Thanks @travisperson. that library, or a similar solution, looks like a non-intrusive solution that gives everyone what they want -- callback API and promise API out of the box. To clarify my earlier comment, I wasn't suggesting adding bluebird to this library ( Promise = require 'bluebird'
ipfsApi = require 'ipfs-api'
ipfs = Promise.promisifyAll ipfsApi At this point, in addition to the usual ipfs.add and ipfs.ls methods which take callbacks, I also have ipfs.addAsync and ipfs.lsAsync, which return promises. Sample usage: put: ({content}) ->
@ipfs.addAsync new @ipfs.Buffer content
.then (items) =>
for item in items
item.Hash
.catch (err) ->
console.error err
fetch: ({rootNodeId}) ->
@ipfs.lsAsync rootNodeId
.then (response) =>
data = response.Objects[0]
@process {rootNodeId, data}
.catch (err) ->
console.error err |
I'm all in on having a promises API if the users of node-ipfs-api are looking for it. However I don't think there will be any valid reason to drop callbacks in favor to promises. If someone wants to volunteer to make that really nice promises API along the side of the callbacks API (+ tests for it), let's do it :) |
On further reading of my prior comment, sorry for sounding like a dick ;P Let me try that again. Adding a promise api would be great! As long as it doesn't degrade the callback api in any way. |
@harlantwood pointed out that users can just promisify the API trivially easy. I would think that's the best route, leaving it to the user, and maybe have a comment in the readme. It keeps our interface smaller and supports both methods. — On Thu, Oct 22, 2015 at 6:41 PM, David Dias notifications@github.com
|
Actually at the moment bluebirds const API = Promise.promisifyAll(require('ipfs-api'))
const api = new API()
api.idAsync().then(id => console.log(id))
// => some id
api.swarm.peersAsync().then(peers => console.log(peers))
// => undefined method peersAsync |
After some more investigation it looks like we can not expose our API easily in a way that const API = require('ipfs-api')
const api = new API('127.0.0.1:5001')
api.id()
.then(id => console.log(id))
.catch(err => console.error(err))
api.id(function (err, id) {
if (err) return console.error(err)
console.log(id)
}) To expose this kind of API we just need to switch the internal generation calls to using promises and then call |
I've a question (following our IRC discuss) Following nodeify example, how can I return a value from inside a callback within the callback? e.g: module.exports = Promise.nodeify(awesomeAPI)
function awesomeAPI(a, b) {
oneLevelDeep (a, b, function (err, res) {
return res // ?? Would this even work?
})
} Another example, taking the .id call Currently self.id = function (id, cb) {
if (typeof id === 'function') {
cb = id
id = null
}
requestAPI('id', id, null, null, cb)
} With nodeify, it would be self.id = function (id) {
if (typeof id === 'function') {
cb = id
id = null
}
requestAPI('id', id, null, null)
} But how would requestAPI pass the value to whom calls .id()? |
Example implmentation: https://github.com/Dignifiedquire/js-ipfs-api/blob/es2015-promises/src/index.js#L88-L95 |
After the several discussions we had so far, I'm understanding that this topic, promises vs callbacks, is way bigger than a simply binary decision or even a compromise between the two. In order to support both APIs the code has be developed using promises and then put a 'callbacks lid' on top so that users can still use callbacks. This could work, but every contributor would have to buy in on promises, which could be ok, however, developing with promises in Node.js (non browser apps), can be a pain because Node.js simply doesn't have a promises API (or a 'promise' of having it in the near future) and it async control flow will be messed up. We could also avoid promises and continue using only callbacks (so far, it has worked well for a ton of JS applications), but as @dignifiedquire pointed out, every library and browser API is moving to promises, specially the React stuff we even use ourselves. This leads me to think that this universal/isomorphic javascript is just an idea built on weak foundations and that we will need to accept having on JS way for browser code and one JS way for Node.js code. |
After a hangout with @diasdavid we have come to the conclusion that we do not want to change all the modules to another async handling style, simply because it would be too much work better spent otherwise. So for all node code we will stick with callbacks, but we want to try to make it possible to easily expose a promisifable version of the API using tools like bluebirds As that is not usable at the moment we are searching for the best way to do that and I have opened petkaantonov/bluebird#840 asking for help, but please feel free to add any suggestions here. |
All methods return a promise when not passed a callback Closes #80
All methods return a promise when not passed a callback Closes #80
Most environments now support the more pleasant API of
Promise
( https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Promise ), that is easier to handle and chain together. We should think about migrating to start using promises instead of callbacks where applicable.List of browsers that supports it current: https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Promise
(IE doesn't support it + some olders versions of other browsers, probably have to provide an existing shim as well...)
In node, promises have been natively supported since 0.12 so shouldn't be an issue there.
The text was updated successfully, but these errors were encountered: