如何绕过'那么's在承诺链中,就像传统的'return'陈述
How can I bypass the rest of the 'then's in a promise chain, like a traditional 'return' statement?
我将放弃我的同步、多线程Java编程世界,拥抱ES6 JavaScript的单线程、异步、基于承诺的世界。我不得不抓住这个概念,将以同步风格编写的函数映射到基于异步promise的函数。我目前使用的是ES6原生承诺和蓝鸟承诺的混合。
我将从一个例子开始为我的问题做准备(Java中的同步例子,ES6中的异步例子):
同步功能
private Object doSomething(Object var1, Object var2) {
Object var3 = blockingFunction(var1);
Object var4 = anotherBlockingFunction(var2, var3);
return var4;
}
基于异步Promise的equivalanet
function doSomething(var1, var2) {
return asyncFunction(var1)
.then(var3 => {
return anotherAsyncFunction(var2, var3);
})
.then(var4 => {
return var4;
});
}
现在我的问题是:是否有一种干净的(即内置的、已经考虑过的)方法来模拟同步return
的想法,以绕过返回链的其余部分?
为了解释,这里还有两个同步和异步的例子:
同步功能
private Object doSomething(Object var1, Object var2) {
Object var3 = blockingFunction(var1);
Object var4 = anotherBlockingFunction(var2, var3);
if (!var4.isValid()) {
return var3;
}
// If var4.isValid() equates to false, we bypass the following statements
// and return the value of var3 as the final value
Object var5 = var4.validateObject();
var5.setSomething(var1);
return var5;
}
(我的猜测是)基于异步承诺的等价物
function doSomething(var1, var2) {
// Predefine variables within this block so they persist between 'then's
let var3;
let var4;
let var5;
let bypassCondition;
return asyncFunction(var1)
.then(result => {
var3 = result;
return anotherAsyncFunction(var2, var3);
})
.then(result => {
var4 = result;
bypassCondition = !var4.valid;
if(bypassCondition) {
return var3;
}
})
.endChain(bypassCondition)
// If the bypassCondition is true, the entire chain would return the value
// of the previous then's return;
// Otherwise, if false, the chain continues
.then(() => {
return var4.validateObject();
})
.then(result => {
var5 = result;
var5.something = var1;
return var5;
});
}
这样的东西已经存在了吗?
我知道这些替代方案,所以也许我可以判断两者是否真的是正确的方法:
- 在链的中间抛出一个异常,并在最后捕获它,以便绕过其他语句
- 将每个后续的
then
的函数封装在if (!bypassCondition)
块中,这样它们就不会全部执行
您正在讨论promise链中的条件流,其中早期返回是一种有用的风格。
是的,这是可能的,通过有条件地分支你的链。注意括号:
function doSomething(var1, var2) {
return asyncFunction(var1)
.then(var3 => anotherAsyncFunction(var2, var3))
.then(var4 => (!var4.isValid())? var3 : var4.validateObject()
.then(var5 => (var5.something = var1, var5)));
}
注意最后一行的缩进,其中.then
与var4.validateObject()
不匹配。
这很好地映射到ES7(在那里我们可以提前进行引导):
async function doSomething(var1, var2) {
let var3 = await asyncFunction(var1);
let var4 = await anotherAsyncFunction(var2, var3);
if (!var4.isValid()) {
return var3;
}
let var5 = await var4.validateObject();
var5.something = var1;
return var5;
}
(您没有指定validateObject
是否是异步的,所以我选择了异步)。
这里的这个答案是我获得这个问题答案的地方。
正如Bergi所指出的,我在这里所做的是分支。我所需要做的就是将继续的分支放在的else块中,如下所示:
function doSomething(var1, var2) {
// Predefine variables within this block so they persist between 'then's
let var3;
let var4;
let var5;
return asyncFunction(var1)
.then(result => {
var3 = result;
return anotherAsyncFunction(var2, var3);
})
.then(result => {
var4 = result;
if(!var4.valid) {
return var3;
}
else {
return Promise.resolve()
.then(() => {
return var4.validateObject();
})
.then(result => {
var5 = result;
var5.something = var1;
return var5;
});
})
}
}
从根本上讲,你不能停止承诺链。尽管看起来我应该能够,但请记住,其他函数会将.then(...)
附加到函数的输出中。该代码没有区分then
语句是出现在一个函数内还是出现在函数外,因此我提出的.endchain(...)
将不得不终止函数外的promise链的所有其他用户,从而使该链最终不可用。
使用这种分支方法,我所追求的传统return
行为得以实现,因为函数结束前链中的最后一个then
是在函数外使用其返回值时链将拾取的位置—在这种情况下,如果var4.valid
是false
,则在return var3;
之后,否则在return var5;
之后。
- jquery if语句返回return wong语句
- 函数在return语句之前返回空对象
- Javascript Return and if/else
- 在ES6 Promise中,我应该在解决/拒绝之前使用return吗
- Angular promise return"未定义的“;值.NET MVC
- Javascript用函数return替换局部变量
- JavaScript中的“return cb()”有缺点吗
- JS-fn()中返回后方括号的含义{return{}[]}
- Node JS,传统的数据结构?(如Set等),任何类似Java.util的node
- 为什么javascript在'return false'
- return false不阻止点击
- 当使用return语句时,循环不会中断
- 如何在不使用return的情况下跳过下一个if语句
- return false不停止表单提交
- 如何通过ajax php将图像上传到服务器本地目录,其中html表单haven't任何传统的提交按钮
- {React jsx babel es6 webpack}如何在渲染中进行注释(return(//||/**/))
- 表单提交没有'调用return false后无法工作
- Jquery ajax return null
- Php ajax return json or html
- 如何绕过'那么's在承诺链中,就像传统的'return'陈述