Promises,将附加参数传递给 then 链
Posted
技术标签:
【中文标题】Promises,将附加参数传递给 then 链【英文标题】:Promises, pass additional parameters to then chain 【发布时间】:2015-12-30 23:25:49 【问题描述】:一个承诺,例如:
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 和 text 参数中访问数据?有没有什么技巧可以避开内部函数?
【问题讨论】:
为什么有人会故意放弃currying?为了使用可怕的bind
方法? - 这也非常慢。
@ftor 我不明白你,你能提供一些代码来澄清一下吗?
【参考方案1】:
也许最直接的答案是:
P.then(function(data) return doWork('text', data); );
或者,因为这是标记ecmascript-6
,使用箭头函数:
P.then(data => doWork('text', data));
我觉得这个可读性最强,写的也不多。
【讨论】:
在您的 es6 示例和“类”中,我将如何将“文本”替换为对创建承诺时迭代的数组中的项目的引用。例如:fetch(request).then(data => this.AssetRetrieved(jData.parms[i].Value, data));
@Reahreic 这听起来像是循环问题中 JS 闭包的变体。 this answer 有用吗?如果没有,请考虑提出一个更详细的新问题。【参考方案2】:
您可以使用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);
【讨论】:
谢谢,有帮助,之前我尝试过 doWork.call(this, 'text'),但数据已替换为 'text'call
就地调用一个函数,bind
创建一个新函数,但是两者都接受一个执行上下文作为它们的第一个参数。【参考方案3】:
使用柯里化。
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 请注意这一点,如果您通过在此函数的第一行执行return new Promise()
将curriedDoWork
创建为一个promise,则该promise 在您调用curriedDoWork()
时立即执行(就像您做..then(curriedDoWork('text'))
@Flame:简短的回答,为方便起见,如果您愿意,可以将承诺包装成一个函数。
@yks,你可以指出这个非常有趣的语法 const curriedWork = text => data => console.log(data + text)
@germain 啊是的,我以前见过这种形式,一定喜欢函数式编程。但是我在某些浏览器中遇到箭头功能中断,所以我现在倾向于避免它。
@yks,只有 Internet Explorer 不支持它并且永远不会支持它,因为 Edge,Internet Explorer 的上一个版本是 2015 年 12 月 9 日。让我们继续吧~【参考方案4】:
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
上下文。
【讨论】:
【参考方案5】:这个问题的新答案是使用箭头函数(它会自动绑定this
并且更具可读性)。谷歌的链接,例如:
https://2ality.com/2016/02/arrow-functions-vs-bind.html
您可以将文本设置为:
this.text = 'text';
P.then(data => doWork(data));
注意:this.text
内的 doWork
将评估为“文本”。
这是上面的jib建议的,那(或这个!)现在应该是公认的答案。
【讨论】:
【参考方案6】:使用它,以便您可以访问承诺正文中的全局变量
var ref=this;
例子
p.then((data)=>
var ref=this;
);
【讨论】:
以上是关于Promises,将附加参数传递给 then 链的主要内容,如果未能解决你的问题,请参考以下文章