New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

pure_promise

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pure_promise

  • 0.0.1
  • Rubygems
  • Socket score

Version published
Maintainers
1
Created
Source

Build Status

PurePromise

My promises library. It tries to be as close to the Promises/A+ spec as possible, with one exception:

A promise callback must return a promise

This makes it slightly more verbose, but it has some nice properties. I'll explain them here later.

Influenced by promise.rb, the Promises/A+ spec, and browsers' implementations of promises (for the stuff that's not #then).

Installation

Add this line to your application's Gemfile:

gem 'pure_promise'

And then execute:

$ bundle

Or install it yourself as:

$ gem install pure_promise

Usage

Making them asynchronous

Note: The defer method does not have to yield in the order in which defer was called, it just has to yield some time in the future.

class EMPromise < PurePromise
  def defer
    EM.next_tick { yield }
  end
end

Creating promises

# Create a fulfilled promise
PurePromise.fulfill(:value)
PurePromise.fulfill

# Create a rejected promise
PurePromise.reject(:value)
PurePromise.reject

# Create a pending promise
PurePromise.new

# Create a promise which fulfills or rejects when fulfill or reject are called.
PurePromise.new do |fulfill, reject|
  if something?
    fulfill.call(:value)
  else
    reject.call(:error)
  end
end

# Create a promise with fulfills/rejects when thenable fulfills/rejects
PurePromise.resolve(thenable)

# Create a promise which is rejected to an exception object, with backtrace properly set.
PurePromise.error # #<RuntimeError: RuntimeError>
PurePromise.error('message') # #<RuntimeError: message>
PurePromise.error(TypeError, 'message') # #<TypeError: message>
PurePromise.error(TypeError.new('message')) # #<TypeError: message>

Mutating promises

A promise can only be mutated once. Once it has transitioned from pending, the value cannot be changed.

promise = Promise.new

# It is recommended to pass a block to new for fulfilling and rejecting promises,
# as this normally makes your code more clear
promise.fulfill(:value)
promise.reject(:value)

# Make promise take on the form of thenable
# This can be any object that implements a semi-compliant then method,
# as described in the Promises/A+ spec
promise.resolve(thenable)

Accessing promises

The only way to access a promise's value is through the then/catch methods.

Each callback must evaluate to a promise. If the action in the callback succeeds, return PurePromise.fulfill, otherwise return PurePromise.reject.

then and catch always return a promise, which fulfills or rejects to the value of the promise returned from the callback when it is executed.

If a callback raises an error, the promise returned by then or catch will be rejected with the error as the value.


# Attach a fulfillment callback
PurePromise.fulfill(:some_value).then do |value|
  puts value.inspect
  PurePromise.fulfill
end
# :some_value

# Attach a rejection callback
PurePromise.error.catch do |error|
  puts error.inspect
  PurePromise.fulfill
end
# #<RuntimeError: RuntimeError>

# Attach both
PurePromise.fulfill(:some_value).then(proc { |value|
  puts value.inspect
  PurePromise.fulfill
}, proc { |error|
  puts error.inspect
  PurePromise.fulfill
})

Shortcomings addressed

This isn't having a dig at anyone else's work, these are just the reasons why I wanted to create my own promises library. I could have got a lot of things wrong too, and I'd love to hear about them in the issues section.

In Promises/A+ Spec

  • You cannot wrap anything that implements a then method in a promise. This bit me when wanting to pass around a faye client in a promise system - and it took me forever to debug. PurePromise addresses this by forcing you to return a promise from your callbacks.

In Promise.rb

  • IMO, being able to retrieve the value of the promise through an accessor is wrong. What do you return when the promise is pending and has no value? Nil? But nil is a valid value for a promise, creating ambiguity.

Design goals

  • Address the above shortcomings.
  • Limit the public api to as small as possible (then, fulfill, reject, resolve). Everything else should just be convenience methods on top of these.

TODO

  • DRY up specs; they are pretty verbose atm.
  • Get 100% mutation coverage
  • Release gem

Contributing

  1. Fork it ( https://github.com/cameron-martin/pure_promise/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

FAQs

Package last updated on 17 Aug 2014

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc