Skip to content

Instantly share code, notes, and snippets.

@algesten
Forked from scott-christopher/promiseApply.js
Last active August 29, 2015 14:26
Show Gist options
  • Save algesten/f8165c3b8c914899c656 to your computer and use it in GitHub Desktop.
Save algesten/f8165c3b8c914899c656 to your computer and use it in GitHub Desktop.
Promise applicative example
# Goals
#
# 1. Mix promise and non-promise arguments
# 2. Behaves like a normal function if all arguments are non-promise
# 3. Returns a promise if any non-promise argument
# 4. Use no promise library, rely on the fact that:
# promise.then(-> a1).then((a2) -> a1 === a2)
# promise.then(-> Promise(a1)).then((a2) -> a1 === a2)
#
# tests if p has .then and in that case returns
# then bound to p.
_isthenable = (p) ->
return false unless p
return false unless typeof p in ['object', 'function']
t = p.then
if typeof t == 'function' then t.bind(p) else false
# first thenable (if any)
_firstthenable = firstfn _isthenable
# :: Promise (a -> b), (a or Promise a) -> Promise b
_promapply = (pfn, parg) ->
fn = null
pfn.then (_fn) ->
fn = _fn
parg
.then (arg) ->
fn(arg)
plift = (f) ->
(as...) ->
first = _firstthenable as # first is a .then
if first
fold as, _promapply, first -> curry(f)
else
f as...
Q = require 'q'
{plift} = require './src/fnuc'
add3 = plift (a, b, c) -> a + b + c
out = console.log.bind console
# print 6 straight away
out add3(1, 2, 3)
# helper to delay stuff
delay = (ms, fn) -> Q.Promise((rs) -> setTimeout rs, ms).then fn
a = delay 500, -> 1
b = delay 1000, -> 2
c = delay 1500, -> 3
# print 6 after 1000ms
add3(1, b, 3).then out
# print 6 after 1500ms
add3(a, b, c).then out
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment