承诺,传递其他参数然后链接


100

一个承诺,例如:

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

在我们调用之后,然后在promise上的方法:

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

doWork函数如下所示:

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

如何避免在doWork中返回内部函数,以便从promise和text参数访问数据?是否有避免内部功能的技巧?


1
为什么有人会故意放弃讽刺?为了使用可怕的bind方法?-这也非常慢。

@ftor我不了解您,能否请您提供一些代码进行说明?
罗兰

Answers:


86

您可以Function.prototype.bind用来创建一个新函数,并将值传递给它的第一个参数,如下所示

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

然后您可以更改doWork

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

现在,text它将实际'text'存在doWorkdata并将成为Promise解决的价值。

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


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

谢谢,这有帮助,我早些时候尝试过doWork.call(this,'text'),但是数据被'text'代替了
user3110667

2
call就地调用一个函数,bind创建一个新函数,但是都接受执行上下文作为它们的第一个参数。
sdgluck 2015年

103

也许最直接的答案是:

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

或者,由于已标记ecmascript-6,请使用箭头功能:

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

我觉得这是最易读的,而且写起来也不太多。


5

使用咖喱。

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

b注意这一点,如果您curriedDoWork通过在return new Promise()函数的第一行执行来创建承诺,则该承诺会在调用后立即执行curriedDoWork()(就像您在..then(curriedDoWork('text'))
Flame

@Flame:简短答案,为方便起见,您可以将promise包装到函数中(如果您愿意)。
尔曼

@yks,您可能已经指出了这种语法,这很有趣const curriedWork = text => data => console.log(data + text)
germain,

1
@germain啊是的,我以前见过这种形式,一定喜欢函数式编程。但是我在某些浏览器中遇到箭头功能中断的情况,因此我现在倾向于避免使用它。
yks

@yks,只有Internet Explorer不支持它,也永远不会,因为Edge,Internet Explorer的上一个版本是2015年12月9日。让我们继续前进
germain

0

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函数内的上下文中。


0

这个问题的新答案是使用箭头功能,该功能会自动绑定“ this”并且更具可读性。Google提供的链接,例如: https //2ality.com/2016/02/arrow-functions-vs-bind.html

您可以像这样设置文本:this.text ='text'P.then(data => doWork(data)); // doWork内的this.text将评估为'text'。

这是由上面的臂架建议的,并且(或此!)现在应该是公认的答案。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.