如何像传统的“ return”声明那样绕过承诺链中的其余“ then”? [英] How can I bypass the rest of the 'then's in a promise chain, like a traditional 'return' statement?

查看:61
本文介绍了如何像传统的“ return”声明那样绕过承诺链中的其余“ then”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我抛弃了我的同步,多线程Java编程世界,而拥抱了ES6 JavaScript的基于单线程,异步,基于Promise的世界。我不得不抓住这种将以同步方式编写的函数映射到基于promise的函数的概念。我目前正在使用ES6本机Promises和Bluebird Promise的混合。

I am leaving behind my synchronous, multi-threaded Java programming world and embracing the single-threaded, asynchronous, promise-based world of ES6 JavaScript. I have had to catch on to this concept of mapping functions written in a synchronous style to async promise-based functions. I am currently using a mix of ES6 native Promises and bluebird promises.

我将从一个示例开始,为我的问题做准备(Java中的同步示例,异步ES6中的示例):

I'll start with an example to set the stage for my question (synchronous examples in Java, async examples in ES6):

同步功能

private Object doSomething(Object var1, Object var2) {
    Object var3 = blockingFunction(var1);
    Object var4 = anotherBlockingFunction(var2, var3);
    return var4;
}

基于异步承诺的Equivlanet

function doSomething(var1, var2) {
    return asyncFunction(var1)
    .then(var3 => {
        return anotherAsyncFunction(var2, var3);
    })
    .then(var4 => {
        return var4;
    });
}

现在这是我的问题:是否干净? (即内置的,已经考虑过)模拟同步返回想法绕过返回链其余部分的方法?

Now here's my question: Is there a clean (i.e. built-in, already thought of) way to simulate the synchronous return idea to bypass the rest of the return chain?

为了说明,这里还有两个更多的同步和异步示例:

To explain, here are two more synchronous and asynchronous examples:

同步功能

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

这样的东西已经存在了吗?

Does something like this already exist?

我知道这些替代方法,所以也许我可以告诉他们这是否是正确的方法:

I am aware of these alternatives, so perhaps I can told whether or not either is actually the right way to do it:


  • 在链的中间抛出一个异常并在末尾捕获它,以便其他语句被绕过

  • 随后的每个然后包装 if(!bypassCondition)块中的函数,以便它们不会全部执行

  • Throw an exception in the middle of the chain and catch it at the end, so that other statements are bypassed
  • Wrap each subsequent then's function in an if (!bypassCondition) block so that they won't all be executed

推荐答案

这里的答案是我在哪里能够获得我对这个问题的答案。

This answer over here is where I was able to obtain my answer to this question.

正如Bergi指出的那样,我在这里正在做分支。我要做的就是将连续分支放入 else块,就像这样:

As Bergi pointed out, what I am doing here is branching. All I need to do is put the continuing branch inside the else block, like so:

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(.。 。),则必须终止该函数的承诺链 之外的所有其他用户,从而使该链最终无法使用。

Fundamentally, you cannot stop a promise chain. Even though it looks like I should be able to, remember that other functions will append .then(...) to the output of your function. The code has no distinction as to if the then statements appear within one function or outside of it, so what I was proposing, .endchain(...), would have to end all other users of the promise chain outside of the function, making the chain ultimately un-useable.

使用此分支方法,我执行的传统返回行为得以完成,因为最后的然后在函数末尾之前的链中,当其返回值在函数之外使用时,链将开始拾取—。在这种情况下,在返回var3之后; 如果 var4.valid false ,或者在返回var5之后; 否则。

Using this branching method, the traditional return behavior I was after is accomplished, because the last then in a chain before the end of the function is where the chain will pick up when its return value is used outside of the function — in this case, either after return var3; if var4.valid is false, or after return var5; otherwise.

这篇关于如何像传统的“ return”声明那样绕过承诺链中的其余“ then”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆