.then(functionReference)和.then(function(value){return functionReference(value)})之间是否存在差异?

时间:2016-12-16 19:20:52

标签: javascript promise

给定用于处理Promise值的命名函数

function handlePromise(data) {
  // do stuff with `data`
  return data
}

a)将命名函数handlePromise作为对.then()

的引用传递
promise.then(handlePromise)

b)使用匿名或命名函数作为.then()的参数,并返回带有handlePromise值的命名函数Promise作为传递给{的匿名或命名函数体内的参数{1}}

.then()

问题

  1. 模式a)和b)之间是否存在差异?

  2. 如果对1的回答是肯定的,那么应该有什么不同 使用任何一种模式时都要考虑?

4 个答案:

答案 0 :(得分:5)

可以创建一个在没有参数传递时存在差异的情况,但它是一个延伸,通常你应该通过f而不是function(x) { return f(x); }x => f(x)因为它更干净。

这是一个导致差异的例子,理由是带参数的函数可能会导致这些参数产生副作用:

function f() {
   if(arguments.length === 0) console.log("win");
   else console.log("Hello World");
}
const delay = ms => new Promise(r => setTimeout(r, ms)); // just a delay
delay(500).then(f); // logs "Hello World";
delay(500).then(() => f()) // logs "win"

答案 1 :(得分:2)

没有区别,function(x){return f(x)} === f

有关详细信息,您可能需要阅读lambda演算中的eta-conversion

答案 2 :(得分:1)

逻辑

从逻辑的角度来看,没有任何东西可以将它们分开。

来源

从源代码和样式的角度来看,我的个人品味是反对内联函数声明,因为它们更难阅读(当阅读别人的代码时,在阅读我自己的艺术作品LOL时)

调试

从调试的角度来看,当嵌套变深时,如果你有一个很长的匿名调用堆栈跟踪,就很难调试。

性能

从性能角度来看,它取决于浏览器。使用Firefox没有显着差异。使用Chrome Canary 60以及之前的所有版本。第一次调用后,内联匿名函数声明比定义的函数语句和函数表达式慢得多。传统和箭头功能都是如此。

比较两种选择并仅对while循环进行计时

var i,j;
const f = a => a;
j = i = 10000;

while(i--) f(i);  // timed loop


while(j--) (a=>a)(j); // timed loop

预定义函数的执行速度比内联函数快870%。

但是我还没有看到任何人在性能关键代码中使用promises,测试机器(win10 32bit)的时间差为f(i)为0.0018μs(*),(a=>a)(i)为0.0157μs

(*)μs表示微秒1 / 1,000,000秒/秒

结论

差异很小到微不足道,更多的是个人品味和风格问题。如果您在团队中工作,请使用其样式指南中列出的样式,如果您是项目主管或自己工作,请使用您最熟悉的内容。

BenjaminGruenbaum中显示的边缘情况回答我认为没有效果,因为他在没有参数的情况下显式调用then(()=>f())中的f()。这与const ff = () => f(); delay(0).then(ff)相同,而不是如何定义函数的怪癖。

答案 3 :(得分:0)

确实存在一个主要区别,虽然不是那么重要,实际上应该避免。 如果直接在then()内部调用handlePromise(),则不允许添加外部参数。如果你在.then( (result) => handle(result, someOtherParam) )里面的函数内部调用它,那么你就可以添加'someotherparam'来调用它。如果你有更大的调用树,它会很方便,但我会避免这种情况并将其传递给整个承诺链。

<强> TLDR; 第一个用.then()结果作为参数调用,后一个是你想要进一步传递的弹性。