Binding a promise handler function to an object

2019-02-16 06:53发布

问题:

I have some code like:

var bar = foo().then(function success(value) {
  // compute something from a value...
}, function failure(reason) {
  // handle an error...
});

How do I bind the failure function to the this object in the context of bar. I know I will have to use myFunc.bind(this) but what do I substitute in place of myFunc?

回答1:

You can use bind like this:

var bar = foo().then(function success(value) {
  // compute something from a value...
}, function failure(reason) {
  // handle an error...
}.bind(this));


回答2:

You currently have an anonymous (although labelled) function for your failure callback:

function failure(reason) {
   // handle an error...
}

As robertklep says, you can immediately call .bind on that anonymous function. However, it might be more readable to use a named function instead, and pass it into .then() as a variable:

function success(value) {
    // compute something from a value...
}
function failure(reason) {
    // handle an error...
}
var bar = foo().then(success, failure.bind(this));


回答3:

What I found very useful is to bind each then()'s [function] handler to the one empty object, so each function could have the access to it. Then the user can set and get the properties in each Promise by this keyword. The unit test frameworks works similarly.

    chainPromiseList([getName,getAge],finalDone,rejectHandle);

    function chainPromiseList(promiseList,finalDone,errHandle){
      var userContext = new UserContext();
      if(typeof finalDone==='function') promiseList.push(finalDone);
      if(typeof errHandle==='function') promiseList.push(errHandle);
      return promiseList.reduce((total,curVal,curInd,arr)=>{
        var last = curInd+1===arr.length;
        var method = last&&typeof errHandle==='function' ? 'catch':'then';
        var concatenated = total[method](curVal.bind(userContext));
        return concatenated;
      },Promise.resolve());
        function UserContext(){};
    }
    
    function getName(){
      return new Promise((resolve,reject)=>{
        setTimeout(()=>{
          console.log('got name!');
          this.name = 'Paul';
          resolve();
        },500);
      });
    }

    function getAge(){
      return new Promise((resolve,reject)=>{
        setTimeout(()=>{
          console.log('got age!');
          this.age = 26;
          resolve();
        },500);
      });
    }

    function finalDone(){
      console.log(`Hello, I'm ${this.name} and I'm ${this.age}yo.`);
    }

    function rejectHandle(msg){
      console.log('Error: ',msg);
    }