当前位置: 首页 > 面试题库 >

什么是“回调地狱”,RX如何以及为什么解决它?

海翔宇
2023-03-14
问题内容

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

什么时候(以哪种设置)发生“回调地狱问题”?

为什么会发生?

“回调地狱”是否总是与异步计算相关?

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

我在Coursera参加了“反应式课程”,Erik
Meijer在他的一次演讲中说RX解决了“回调地狱”的问题。我在Coursera论坛上问什么是“回调地狱”,但我没有明确的答案。

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


问题答案:

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

Javascript中的问题在于,“冻结”计算并使“其余部分”(异步地)执行的唯一方法是将“其余部分”放入回调中。

例如,假设我要运行如下代码:

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

如果现在我想使getData函数异步,这意味着我有机会在等待其他代码返回值时运行一些其他代码,会发生什么情况?在Javascript中,唯一的方法是使用延续传递样式重写所有与异步计算有关的内容:

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

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

2)什么时候(以哪种设置)发生“回调地狱问题”?

当您的代码中有很多回调函数时!与您的代码一起使用的人越多,与他们的合作就越困难,而当您需要执行循环,try-catch块之类的事情时,情况就变得尤其糟糕。

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

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

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

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

//ugh!

我们在StackOverflow上收到的许多问题询问如何做这种事情,这证明了它是多么令人困惑:)

3)为什么会发生?

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

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

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

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

5)您能否也请通过该简单示例说明RX如何解决“回调地狱问题”。

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

在Python中,我们可以使用类似于以下内容的代码来实现该先前的循环示例:

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

myGen = myLoop()

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



 类似资料:
  • 本文向大家介绍如何解决异步回调地狱?相关面试题,主要包含被问及如何解决异步回调地狱?时的应答技巧和注意事项,需要的朋友参考一下 参考回答:  

  • 问题内容: 我在使用Node.js并将文件上传到服务器时遇到问题。为了将文件上传到服务器,我使用了这个插件。开始将文件上传到服务器时,Node.js进程崩溃并显示错误: 错误:ENOSPC。 服务器代码未运行。 问题答案: 运行以下命令以避免使用ENOSPC: 对于Arch Linux,将此行添加到: 然后执行: 这也将在重新启动后持续存在。 技术细节来源

  • 问题内容: 为什么用显示器输出该日期? 如何转换为? 问题答案: 在PHP 5.4中,可以使用: 否则,您必须进行一些琐碎的后处理 请注意,这是表示JSON 的有效方法。

  • 问题内容: 一个简单的问题,但它已经困扰了我一段时间。 MySQL中的“开销”是什么,我应该担心吗? 单击“优化表”是否能真正解决问题? 问题答案: 开销似乎是数据库用来运行某些查询的临时磁盘空间,因此,您只需要担心这会变得非常高。 您可以将“优化表”与硬盘驱动器的碎片整理进行比较。 我引用: 随着时间的推移,每个数据库都需要某种形式的维护,以使其保持 最佳 性能水平。清除已删除的行,重新排序,压

  • 我正在查看的源代码,在api文件夹中有一个文件,内容如下: 我听说这个文件是打字稿类型定义。这是什么?为什么需要它?

  • 这个问题不同于关于调试异常的一般建议,因为问题的原因并不总是在调用堆栈上,而特定的建议是必要的。