Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The correct way to bind object to Promise.then() argument [duplicate]

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.

like image 561
ThomasReggi Avatar asked Jun 23 '15 21:06

ThomasReggi


People also ask

What is Promise resolve () then?

resolve() The Promise. resolve() method "resolves" a given value to a Promise . If the value is a promise, that promise is returned; if the value is a thenable, Promise. resolve() will call the then() method with two callbacks it prepared; otherwise the returned promise will be fulfilled with the value.

How do you bind an object in JavaScript?

We use the Bind() method to call a function with the this value, this keyword refers to the same object which is currently selected . In other words, bind() method allows us to easily set which object will be bound by the this keyword when a function or method is invoked.

What does Promise all () do?

all() The Promise. all() method takes an iterable of promises as an input, and returns a single Promise that resolves to an array of the results of the input promises. This returned promise will fulfill when all of the input's promises have fulfilled, or if the input iterable contains no promises.

What is argument binding in JavaScript?

bind is a method on the prototype of all functions in JavaScript. It allows you to create a new function from an existing function, change the new function's this context, and provide any arguments you want the new function to be called with.


1 Answers

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

like image 191
thefourtheye Avatar answered Oct 09 '22 01:10

thefourtheye