我认为这是您应该做的。
分割链
因为这两个函数都将使用amazingData,所以将它们放在专用函数中是有意义的。我通常在每次要重用一些数据时都这样做,因此它总是以函数arg的形式出现。
当您的示例正在运行一些代码时,我将假设它们都在一个函数中声明。我将其称为toto()。然后,我们将有另一个函数将同时运行afterSomething()和afterSomethingElse()。
function toto() {
return somethingAsync()
.then( tata );
}
您还会注意到我添加了一个return语句,因为它通常是Promises的处理方式-您总是返回一个promise,因此我们可以根据需要保持链接。在这里,somethingAsync()将产生令人惊奇的数据,并且它将在新函数内的任何地方可用。
现在,这个新函数通常看起来像是依赖于processAsync()还是异步的?
processAsync不是异步的
如果processAsync()不是异步的,则没有理由使事情复杂化。一些旧的良好的顺序代码会成功。
function tata( amazingData ) {
var processed = afterSomething( amazingData );
return afterSomethingElse( amazingData, processed );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
请注意,afterSomethingElse()是否执行异步操作都没有关系。如果确实如此,则将返回承诺,并且链可以继续。如果不是,那么将返回结果值。但是因为函数是从then()调用的,所以无论如何该值都将被包装到一个Promise中(至少在原始Javascript中)。
processAsync异步
如果processAsync()是异步的,则代码看起来会稍有不同。在这里,我们认为afterSomething()和afterSomethingElse()不会在其他任何地方重用。
function tata( amazingData ) {
return afterSomething()
.then( afterSomethingElse );
function afterSomething( /* no args */ ) {
return processAsync( amazingData );
}
function afterSomethingElse( processedData ) {
}
}
与afterSomethingElse()之前相同。它可以是异步的也可以不是异步的。将返回承诺,或将值包装到已解决的承诺中。
您的编码风格与我以前的工作非常接近,这就是为什么即使两年后我仍然回答的原因。我不喜欢到处都有匿名功能。我觉得很难看。即使在社区中很常见。这是因为,我们更换了回调地狱由承诺,炼狱。
我也喜欢在不断的函数的名称,然后短。无论如何,它们只会在本地定义。而且大多数时候,他们会调用其他地方定义的另一个函数(可重复使用)来完成这项工作。我什至只对具有1个参数的函数执行此操作,因此在向函数签名中添加/删除参数时,不需要进出函数。
吃的例子
这是一个例子:
function goingThroughTheEatingProcess(plenty, of, args, to, match, real, life) {
return iAmAsync()
.then(chew)
.then(swallow);
function chew(result) {
return carefullyChewThis(plenty, of, args, "water", "piece of tooth", result);
}
function swallow(wine) {
return nowIsTimeToSwallow(match, real, life, wine);
}
}
function iAmAsync() {
return Promise.resolve("mooooore");
}
function carefullyChewThis(plenty, of, args, and, some, more) {
return true;
}
function nowIsTimeToSwallow(match, real, life, bobool) {
}
不要过多地关注Promise.resolve()。这只是创建已解决承诺的快速方法。我试图通过此方法来实现的是,将我正在运行的所有代码都放在一个位置-那时在。具有描述性更强的名称的所有其他功能都是可重用的。
这种技术的缺点是定义了很多功能。但是,为了避免到处都具有匿名功能,恐怕这是必要的痛苦。还有什么风险:堆栈溢出?(玩笑!)
使用其他答案中定义的数组或对象也可以。这是凯文·里德(Kevin Reid)提出的答案。
您还可以使用bind()或Promise.all()。请注意,它们仍然需要您拆分代码。
使用绑定
如果您想保持函数的可重用性,但又不需要保留其中的内容那么短,则可以使用bind()。
function tata( amazingData ) {
return afterSomething( amazingData )
.then( afterSomethingElse.bind(null, amazingData) );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
为简单起见,当调用函数时,bind()会将args列表(第一个参数除外)放在函数之前。
使用Promise.all
在您的帖子中,您提到了spread()的用法。我从未使用过您正在使用的框架,但是这里是您应该如何使用它的方式。
有些人认为Promise.all()是所有问题的解决方案,所以我想值得一提。
function tata( amazingData ) {
return Promise.all( [ amazingData, afterSomething( amazingData ) ] )
.then( afterSomethingElse );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( args ) {
var amazingData = args[0];
var processedData = args[1];
}
您可以将数据传递给Promise.all() -注意数组的存在-只要有诺言,但要确保所有诺言都不会失败,否则它将停止处理。
而且,除了从args参数定义新变量之外,您还应该可以使用spread()代替then()进行各种出色的工作。