0

I'm trying to figure out how to do a late bind of a promise function parameter. In most cases, I like to have promise flow just be a series of function names, so that it reads like a series of steps (unless it's a one liner like below)

(adjustedDate) => { aGreatFunctionNeedingADateInput.bind(undefined,adjustedDate) }

Here's an example. The function is waiting for a date, as it's late binded input, and that input will come from some step in the promise chain before it.

let aGreatFunctionNeedingADateInput = greatFunction.bind(undefined, x, y);
somePromise().then(functionThatMightChangeDate)
             .then( (adjustedDate) => {
                    aGreatFunctionNeedingADateInput.bind(undefined,adjustedDate)
             })                        
             .then(aGreatFunctionNeedingADateInput)

I know there's a lot of strange and potentially wrong scoping going on here, but essentially I want to bind the last argument of a promise function as a last step, in case it gets changed along the way. Let me know if this is possible.

UPDATE:

Found this example at this link: http://lhorie.github.io/mithril-blog/curry-flavored-promises.html

Which achieves a similar result except that it does the binding to a fixed value (John Doe) at creation rather than in the middle of the promise chain like I tried to do below. Similar idea but I can probably adapt it to my uses.

var createdBy = function(user, items) {
    return items.filter(function(item) {
        return item.createdBy == user
    });
};

m.request({method: "GET", url: "/api/projects"})
    .then(pastItems) // filter past projects
    .then(createdBy.bind(this, "John Doe")) // filter projects created by john doe
    .then(log) // log past projects created by john doe
maschwenk
  • 569
  • 1
  • 9
  • 20
  • is there a reason you are using `bind` instead of just passing parameters to the function? for your use case I'm a little confused what you are trying to accomplish, it seems to me you just need to call `aGreatFunctionNeedingADateInput` in your `then(..` block rather then above. – Sanketh Katta Jan 30 '16 at 01:12
  • I can't quite tell what you're trying to do, but here's a whole bunch of options for letting a later function in the promise chain have access to some earlier results: [Chain promise results](http://stackoverflow.com/questions/28714298/bluebird-chain-promises/28714863#28714863). You obviously can't `.bind()` the value early if you want the value to be able to change. You could `.bind()` an object reference and have the data be a property on that object which could be changed along the way. But, the usual way to solve this would be to just use a local variable in a shared scope. – jfriend00 Jan 30 '16 at 01:19
  • You both raise good points. @jfriend00 looking at your example though (Assign Intermediate Results to Higher Scope), I'm confused why my method doesn't work. That variable should be in scope. HOWEVER, depending on the binding time of the `then.` clauses, they may be using some stale value. I suppose due to promises' asynchronous nature, the js engine would probably initialize all the functions/closures, reach the bottom of the code and then start actually executing the promise chain? That would explain it. – maschwenk Jan 30 '16 at 22:14
  • I know what I was doing is way overkill/convoluted, I had just been looking at some functional programming examples where they were currying functions, waiting until the very last moment to bind the critical argument, then evaluating it. I was trying to see how that kind of concept could be applied here. – maschwenk Jan 30 '16 at 22:18
  • Actually, just found a similar example of what I'm trying to do, I'm not as crazy as I thought! http://lhorie.github.io/mithril-blog/curry-flavored-promises.html – maschwenk Jan 30 '16 at 22:26
  • @maschwenk - Your code example doesn't show where `adjustedDate` is modified or where you want to use the modified value so I don't really follow precisely what you're trying to do. As the link I referenced earlier shows, you can pass a value on through `.then()` handlers by making it the resolved value of previous promises or you can nest and use a shared scope to pass state along. – jfriend00 Jan 30 '16 at 22:26
  • Yes, you're new understanding that the `.this()` bindings all happen originally and THEN the async functions start to return and chain is true. That's why you can't late `.bind()` in this circumstance. You can use an anonymous function and then pass the current value of the variable to a `.then()` handler. – jfriend00 Jan 30 '16 at 22:32
  • yes, you're right, that's the reason you can't change the binding. I think maybe the cleanest way is in that link. Just make that function curried and in the promise before the call to `aGreatFunctionNeedingADateInput` just return it into the promise chain and it'll automatically gobble it up as the last input. Hope I explained that properly. – maschwenk Jan 30 '16 at 22:35

1 Answers1

0

You are overthinking it.

"Late binding" is what we generally call "passing", therefore don't bind.

.then((adjustedDate) => aGreatFunctionNeedingADateInput(adjustedDate))

or

.then(aGreatFunctionNeedingADateInput)
Roamer-1888
  • 19,138
  • 5
  • 33
  • 44