Code Monkey home page Code Monkey logo

Comments (18)

dignifiedquire avatar dignifiedquire commented on May 16, 2024

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.

from js-ipfs-http-client.

RichardLitt avatar RichardLitt commented on May 16, 2024

I agree that this doesn't need to be prioritized. If it works, let it stay as it is.

from js-ipfs-http-client.

harlantwood avatar harlantwood commented on May 16, 2024

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

from js-ipfs-http-client.

victorb avatar victorb commented on May 16, 2024

@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 ipfs.add.

@harlantwood Oh, didn't know about Bluebird's promisifyAll, is using native promises in the background? Nice reference though, seems simple enough.

from js-ipfs-http-client.

RichardLitt avatar RichardLitt commented on May 16, 2024

@victorbjelkholm:

cosmetic change

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.

from js-ipfs-http-client.

victorb avatar victorb commented on May 16, 2024

@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.

from js-ipfs-http-client.

bcomnes avatar bcomnes commented on May 16, 2024

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.

from js-ipfs-http-client.

travisperson avatar travisperson commented on May 16, 2024

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

from js-ipfs-http-client.

harlantwood avatar harlantwood commented on May 16, 2024

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 (node-ipfs-api) -- I was pointing out that as a user of the library, I am consuming a promise API right now, thanks to the help of Bluebird's awesome promisifyAll method. My code looks something like:

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

from js-ipfs-http-client.

daviddias avatar daviddias commented on May 16, 2024

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 :)

from js-ipfs-http-client.

bcomnes avatar bcomnes commented on May 16, 2024

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.

from js-ipfs-http-client.

jbenet avatar jbenet commented on May 16, 2024

@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.


Sent from Mailbox

On Thu, Oct 22, 2015 at 6:41 PM, David Dias [email protected]
wrote:

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 :)

Reply to this email directly or view it on GitHub:
#80 (comment)

from js-ipfs-http-client.

dignifiedquire avatar dignifiedquire commented on May 16, 2024

Actually at the moment bluebirds Promise.promisifyAll doesn't work properly, as it tries to go up the prototype chain to promisify nested methods. But at the moment the implementation does not use the prototype chain, which has the result that this will fail:

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

from js-ipfs-http-client.

dignifiedquire avatar dignifiedquire commented on May 16, 2024

After some more investigation it looks like we can not expose our API easily in a way that Promise.promisifyAll(require('ipfs-api')) will work, as we are using nested objects, and those are skipped by this promisification call.
My suggestion is to go the way that is best for the consumers and expose an api that does callbacks and promises at the same time. This would work like this:

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 Promise.nodeify on them, using the Promise package, which is small and node + browser compatible.

from js-ipfs-http-client.

daviddias avatar daviddias commented on May 16, 2024

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()?

from js-ipfs-http-client.

dignifiedquire avatar dignifiedquire commented on May 16, 2024

Example implmentation: https://github.com/Dignifiedquire/js-ipfs-api/blob/es2015-promises/src/index.js#L88-L95

from js-ipfs-http-client.

daviddias avatar daviddias commented on May 16, 2024

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.

from js-ipfs-http-client.

dignifiedquire avatar dignifiedquire commented on May 16, 2024

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 promisfiyAll.

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.

from js-ipfs-http-client.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.