Promises, pass additional parameters to then chain

后端 未结 5 1788
南旧
南旧 2020-11-28 21:10

A promise, just for example:

var P = new Promise(function (resolve, reject) {
  var a = 5;
  if (a) {
    setTimeout(function(){
      resolve(a);
    }, 3000         


        
相关标签:
5条回答
  • 2020-11-28 21:42

    Perhaps the most straightforward answer is:

    P.then(function(data) { return doWork('text', data); });
    

    Or, since this is tagged ecmascript-6, using arrow functions:

    P.then(data => doWork('text', data));
    

    I find this most readable, and not too much to write.

    0 讨论(0)
  • 2020-11-28 21:44

    Lodash offers a nice alternative for this exact thing.

     P.then(_.bind(doWork, 'myArgString', _));
    
     //Say the promise was fulfilled with the string 'promiseResults'
    
     function doWork(text, data) {
         console.log(text + " foo " + data);
         //myArgString foo promiseResults
     }
    

    Or, if you'd like your success function to have only one parameter (the fulfilled promise results), you can utilize it this way:

    P.then(_.bind(doWork, {text: 'myArgString'}));
    
    function doWork(data) {
        console.log(data + " foo " + this.text);
        //promiseResults foo myArgString
    }
    

    This will attach text: 'myArgString' to the this context within the function.

    0 讨论(0)
  • 2020-11-28 21:47

    Use currying.

    var P = new Promise(function (resolve, reject) {
        var a = 5;
        if (a) {
            setTimeout(function(){
                resolve(a);
            }, 3000);
        } else {
            reject(a);
        }
    });
    
    var curriedDoWork = function(text) {
        return function(data) {
            console.log(data + text);
        }
    };
    
    P.then(curriedDoWork('text'))
    .catch(
        //some error handling
    );
    
    0 讨论(0)
  • 2020-11-28 21:53

    You can use Function.prototype.bind to create a new function with a value passed to its first argument, like this

    P.then(doWork.bind(null, 'text'))
    

    and you can change doWork to,

    function doWork(text, data) {
      consoleToLog(data);
    }
    

    Now, text will be actually 'text' in doWork and data will be the value resolved by the Promise.

    Note: Please make sure that you attach a rejection handler to your promise chain.


    Working program: Live copy on Babel's REPL

    function doWork(text, data) {
      console.log(text + data + text);
    }
    
    new Promise(function (resolve, reject) {
        var a = 5;
        if (a) {
          setTimeout(function () {
            resolve(a);
          }, 3000);
        } else {
          reject(a);
        }
      })
      .then(doWork.bind(null, 'text'))
      .catch(console.error);
    
    0 讨论(0)
  • 2020-11-28 21:59

    The new answer to this question is to use arrow functions (which automatically bind the this and are much more readable). Google for links such as: https://2ality.com/2016/02/arrow-functions-vs-bind.html

    You can set the text like:

    this.text = 'text';
    P.then(data => doWork(data));
    

    Note: this.text inside doWork will evaluate to 'text'.

    This is suggested by jib above and that (or this!) should be the accepted answer now.

    0 讨论(0)
提交回复
热议问题