承诺,传递额外的参数到 then 链

Promises, pass additional parameters to then chain

承诺,举个例子:

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

在我们调用 promise 的 .then() 方法后:

P.then(doWork('text'));

那么 doWork 函数如下所示:

function doWork(data) {
  return function(text) {
    // sample function to console log
    consoleToLog(data);
    consoleToLog(b);
  }
}

如何避免在 doWork 中返回内部函数,以访问来自 promise 和文本参数的数据?有什么技巧可以避免内部函数吗?

您可以使用 Function.prototype.bind 创建一个新函数,并将值传递给它的第一个参数,就像这样

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

您可以将 doWork 更改为,

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

现在,text 实际上是 doWork 中的 'text',而 data 将是 Promise 解析的值。

注意:请确保将拒绝处理程序附加到承诺链。


工作程序: 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);

也许最直接的答案是:

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

或者,因为这是标记 ecmascript-6,使用箭头函数:

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

我觉得这篇文章最易读,写起来也不多。

Lodash 提供了一个很好的替代品。

 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
 }

或者,如果您希望成功函数只有一个参数(已履行的承诺结果),您可以这样使用它:

P.then(_.bind(doWork, {text: 'myArgString'}));

function doWork(data) {
    console.log(data + " foo " + this.text);
    //promiseResults foo myArgString
}

这会将 text: 'myArgString' 附加到函数内的 this 上下文。

使用柯里化。

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

这个问题的新答案是使用箭头函数 (自动绑定 this 并且可读性更高)。 Google 用于链接,例如: https://2ality.com/2016/02/arrow-functions-vs-bind.html

您可以将文本设置为:

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

注意:doWork 中的 this.text 将计算为 'text'。

这是上面的 jib 建议的,那个(或这个!)现在应该是公认的答案。

使用它以便您可以访问承诺主体内的全局变量

var ref=this;

示例

p.then((data)=>{
  var ref=this;
});