什么是“回调地狱"?以及RX如何以及为什么解决它? [英] What is "callback hell" and how and why does RX solve it?

查看:176
本文介绍了什么是“回调地狱"?以及RX如何以及为什么解决它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以给出一个清晰的定义,以及一个简单的示例,为不懂JavaScript和node.js的人解释什么是回调地狱"吗?

Can someone give a clear definition together with a simple example that explains what is a "callback hell" for someone who does not know JavaScript and node.js ?

何时(以哪种设置)发生回调地狱问题"?

When (in what kind of settings) does the "callback hell problem" occur?

为什么会发生?

回调地狱"是否始终与异步计算相关?

Is "callback hell" always related to asynchronous computations?

还是在单线程应用程序中也可能发生回调地狱"?

Or can "callback hell" occur also in a single threaded application?

我在Coursera参加了Reactive Course,Erik Meijer在他的一次演讲中说,RX解决了回调地狱"的问题.我在Coursera论坛上问什么是回调地狱",但我没有明确的答案.

I took the Reactive Course at Coursera and Erik Meijer said in one of his lectures that RX solves the problem of "callback hell". I asked what is a "callback hell" on the Coursera forum but I got no clear answer.

在一个简单的示例中解释了回调地狱"之后,您还可以说明在该简单示例中RX如何解决回调地狱问题"吗?

After explaining "callback hell" on a simple example, could you also show how RX solves the "callback hell problem" on that simple example?

推荐答案

1)对于不了解javascript和node.js的人来说,回调地狱"是什么?

另一个问题有一些Javascript回调地狱的示例: Javascript中的问题在于,冻结"计算并使其余部分"(异步地)执行的唯一方法是将其余部分"放入回调中.

The problem in Javascript is that the only way to "freeze" a computation and have the "rest of it" execute latter (asynchronously) is to put "the rest of it" inside a callback.

例如,说我想运行如下代码:

For example, say I want to run code that looks like this:

x = getData();
y = getMoreData(x);
z = getMoreData(y);
...

如果现在我想使getData函数异步,那意味着我有机会在等待其他代码返回值时运行一些其他代码,会发生什么?在Javascript中,唯一的方法是使用

What happens if now I want to make the getData functions asynchronous, meaning that I get a chance to run some other code while I am waiting for them to return their values? In Javascript, the only way would be to rewrite everything that touches an async computation using continuation passing style:

getData(function(x){
    getMoreData(x, function(y){
        getMoreData(y, function(z){ 
            ...
        });
    });
});

我认为我不需要说服任何人此版本比以前的版本丑陋. :-)

I don't think I need to convince anyone that this version is uglier than the previous one. :-)

当代码中有很多回调函数时!在代码中包含的代码越多,与它们的协作就越困难,而在需要执行循环,try-catch块之类的事情时,这种情况就变得尤为糟糕.

When you have lots of callback functions in your code! It gets harder to work with them the more of them you have in your code and it gets particularly bad when you need to do loops, try-catch blocks and things like that.

例如,据我所知,在JavaScript中执行一系列异步函数的唯一方法是在递归函数之后运行一个异步函数.您不能使用for循环.

For example, as far as I know, in JavaScript the only way to execute a series of asynchronous functions where one is run after the previous returns is using a recursive function. You can't use a for loop.

// we would like to write the following
for(var i=0; i<10; i++){
    doSomething(i);
}
blah();

相反,我们可能需要结束写作:

Instead, we might need to end up writing:

function loop(i, onDone){
    if(i >= 10){
        onDone()
    }else{
        doSomething(i, function(){
            loop(i+1, onDone);
        });
     }
}
loop(0, function(){
    blah();
});

//ugh!

我们在StackOverflow上获得的问题数量,问如何做这种事情,证明了它是多么令人困惑:)

The number of questions we get here on StackOverflow asking how to do this kind of thing is a testament to how confusing it is :)

之所以发生这种情况,是因为在JavaScript中,延迟计算以使其在异步调用返回之后运行的唯一方法是将延迟的代码放入回调函数中.您不能延迟以传统的同步样式编写的代码,因此最终到处都有嵌套的回调.

It occurs because in JavaScript the only way to delay a computation so that it runs after the asynchronous call returns is to put the delayed code inside a callback function. You cannot delay code that was written in traditional synchronous style so you end up with nested callbacks everywhere.

异步编程与并发有关,而单线程与并行性有关.这两个概念实际上不是一回事.

Asynchronous programming has to do with concurrency while a single-thread has to do with parallelism. The two concepts are actually not the same thing.

您仍然可以在单个线程上下文中拥有并发代码.实际上,JavaScript是回调地狱的女王,是单线程的.

You can still have concurrent code in a single threaded context. In fact, JavaScript, the queen of callback hell, is single threaded.

并发性和并行性之间有什么区别?

我对RX一点都不了解,但是通常可以通过在编程语言中添加对异步计算的本机支持来解决此问题.实现可能有所不同,包括:异步,生成器,协程和callcc.

I don't know anything about RX in particular, but usually this problem gets solved by adding native support for asynchronous computation in the programming language. The implementations can vary and include: async, generators, coroutines, and callcc.

在Python中,我们可以使用以下内容实现上一个循环示例:

In Python we can implement that previous loop example with something along the lines of:

def myLoop():
    for i in range(10):
        doSomething(i)
        yield

myGen = myLoop()

这不是完整的代码,但是其思想是收益"会暂停我们的for循环,直到有人调用myGen.next().重要的是,我们仍然可以使用for循环来编写代码,而无需像在递归loop函数中那样进行由内而外"的逻辑.

This is not the full code but the idea is that the "yield" pauses our for loop until someone calls myGen.next(). The important thing is that we could still write the code using a for loop, without needing to turn out logic "inside out" like we had to do in that recursive loop function.

这篇关于什么是“回调地狱"?以及RX如何以及为什么解决它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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