【问题标题】:Angular 6 avoid callback hellAngular 6 避免回调地狱
【发布时间】:2018-11-06 17:39:38
【问题描述】:

来自 AngularJS,我正在努力解决下一个问题。我需要一个返回对象的函数(我们称它为 A,但在该函数中包含的所有请求都得到解决之前,无法返回此对象。过程应该是这样的:

  1. 对象 A 是从远程服务器下载的
  2. 使用 A,我们对另一个对象 (B) 进行操作
    1. B 从服务器下载
    2. B 使用来自 A 的一些属性进行了修补
  3. 使用 AB 的结果,我们对第三个对象 C 进行操作
    1. C从服务器下载
    2. C 使用来自 AB 的一些属性进行了修补
  4. BC处理后,函数必须返回A

我想了解如何使用 rxjs 来做这样的事情,但是对于 Angular 6,互联网上的大多数示例似乎已被弃用,并且那里的教程并没有真正的帮助我。而且我无法修改后端以使其更加优雅。非常感谢。

【问题讨论】:

    标签: rxjs angular6


    【解决方案1】:

    考虑以下 Observable:

    const sourceA = httpClient.get(/*...*/);
    const sourceB = httpClient.get(/*...*/);
    const sourceC = httpClient.get(/*...*/);
    

    httpClient 是 Angular 的 HTTPClient

    您描述的操作顺序可能如下所示:

     const A = sourceA.pipe(
        switchMap(a => sourceB.pipe(
            map(b => {
                // do some operation using a and b.
                // Return both a and b in an array, but you can
                // also return them in an object if you wish.
                return [a,b]; 
            })
        )),
        switchMap(ab => sourceC.pipe(
            map(c => {
                // do some operations using a, b, and/or c.
                return a;
           }) 
        ))
    );
    

    现在你只需要订阅A

    A.subscribe(a => console.log(a));
    

    您可以阅读有关 RxJs 运算符的信息 here

    【讨论】:

    • 谢谢。它终于起作用了。而且链接的资源非常有用。
    【解决方案2】:

    嗯,首先,在我看来,正如所描述的,这个函数调用会以某种方式阻塞调用进程,直到所有指定的事件都发生——当然这在 JavaScript 中是不合理的。

    因此,首先,我认为您的函数应该需要一个回调,作为它的唯一参数,当一切最终发生时,该回调将被调用。

    现在 - 关于“如何优雅地处理步骤 1、2 和 3” ...立即想到的是 有限状态机 (FSM) 的概念 算法。

    假设您的函数调用导致一个新的“请求”被放置在某个请求表队列中,并且,如果需要,一个计时器请求(设置为在 1 毫秒内关闭)为该队列提供服务。 (除其他外,该条目将包含对您的回调的引用。)我们还假设该请求被赋予了一个随机字符串“nonce”,它将用于唯一标识它:这将传递给各种外部请求和必须包含在他们的相应回复中。

    FSM的想法是请求会有一个状态,(属性),比如:DOWNLOADING_FROM_B,B_DOWNLOADS_COMPLETEDOWNLOADING_FROM_CC_REQUESTS_COMPLETE 等等。这样,每个将在这个完全异步过程中发挥作用的回调将 (1) 能够通过其随机数定位请求条目,然后 (2) em> 仅基于对条目的state 的检查,明确地“知道下一步该做什么”和“要分配什么新状态(如果有)”。

    例如,当状态达到C_REQUESTS_COMPLETE 时,就应该调用您最初提供的回调,并删除请求表条目。

    您可以轻松地绘制出在任意复杂场景中可能发生的所有“状态转换”(哪些状态可以导致哪些状态,以及当它们发生时要做什么),无论您是否真的创建了一个数据结构来表示所谓的“状态表”,尽管有时这样做会更加优雅(!)。 (可能是混乱的决策逻辑被简单地推到一个简单的表查找中。)

    当然,这是一种经典算法,适用于——并且已经被用于——“太阳下的每一种编程语言”。 (很多硬件设备也使用它。)

    【讨论】:

      猜你喜欢
      • 2017-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-18
      • 2016-03-27
      • 2015-08-01
      • 2018-09-11
      • 1970-01-01
      相关资源
      最近更新 更多