I found out the hard way that one can't simply just pass in a object's function into the Bluebird then
. I'm assuming that Bluebird's then
is doing some magic and wrapping the passed in function in an anonymous function. So I attached a .bind
to the function and it worked. Is this the correct way to do this with bluebird? Or is there some better way?
var Promise = require("bluebird")
var Chair = function(){
this.color = "red"
return this
}
Chair.prototype.build = function(wood){
return this.color + " " + wood
}
var chair = new Chair()
//var x = chair.build("cherry")
Promise.resolve("cherry")
.then(chair.build.bind(chair)) // color is undefined without bind
.then(console.log)
I know none of this is async so please bare with the sync example, my usage is async.
So I attached a
.bind
to the function and it worked. Is this the correct way to do this with bluebird?
Yes, that is one way to retain the context. You can also pass an anonymous function (you might already know this).
Promise.resolve("cherry")
.then(function (value) {
return chair.build(value);
})
.then(console.log);
Or is there some better way?
You can actually use bluebird's Promise.bind
method, like this
Promise.resolve("cherry")
.bind(chair)
.then(chair.build)
.then(console.log)
Now, whenever the Promise handlers (fulfill handlers or rejection handlers) are called, inside the function, this
will refer the chair
object only.
Note 1: In this specific case, console.log
also gets this
as chair
object, but it still works fine, because, in Node.js, console.log
function is defined not only on the prototype bu also on the object itself, bound to the console
object. The corresponding code is here.
Note 2: If different handlers need different contexts, then better write anonymous functions. In that case, Promise.bind
will not help much. But if you choose to use it, then you have to use different contexts for each of the handlers and your code might look something like this
var chair1 = new Chair("red")
var chair2 = new Chair("green")
Promise.resolve("cherry")
.bind(chair1) // Changing the binding to `chair1`
.then(chair1.build)
.tap(console.log)
.bind(chair2) // Changing the binding to `chair2`
.then(chair2.build)
.tap(console.log);