Node.js程序不会在“try{}”之后运行“finally{}”块并以代码0退出

Node.js程序不会在“try{}”之后运行“finally{}”块并以代码0退出,node.js,rxjs,Node.js,Rxjs,今天,我在Node.js中用RxJS编写了一些代码,得到了非常好的结果:程序运行try{}块,但根本没有运行finally{}块,在try{}块中使用代码0退出 缩短代码后,为了重现此问题,步骤如下: 首先创建一个名为subject的BehaviorSubject 调用subject.asObservable().share()并获取名为obs 调用obs.subscribe() 调用等待obs.first().toPromise() 最后,程序执行一个非常有线的行为:退出try{}块,而不在下

今天,我在Node.js中用RxJS编写了一些代码,得到了非常好的结果:程序运行
try{}
块,但根本没有运行
finally{}
块,在
try{}
块中使用代码0退出

缩短代码后,为了重现此问题,步骤如下:

  • 首先创建一个名为
    subject
    BehaviorSubject
  • 调用
    subject.asObservable().share()
    并获取名为
    obs
  • 调用obs.subscribe()
  • 调用
    等待obs.first().toPromise()
  • 最后,程序执行一个非常有线的行为:退出
    try{}
    块,而不在下面的
    finally{}
    块中运行代码

    复制它的TypeScript代码如下:运行它,您将得到一行输出:
    1。在尝试之前
    ,这不是预期的

    import {
      BehaviorSubject,
    }                     from 'rxjs/Rx'
    
    async function main() {
      const subject = new BehaviorSubject<number>(-1)
      const obs = subject.asObservable().share()
    
      /**
       * if comment the following line, this program will output right as the following three lines:
       *
       * 1. BEFORE TRY
       * 2. AFTER TRY
       * 3. FINALLY
       *
       * otherwise, the output will only be:
       *
       * 1. BEFORE TRY
       *
       * very wired!
       *
       */
      obs.subscribe()
    
      try {
        console.log('1. BEFORE TRY')
    
        await obs.first().toPromise()
    
        console.log('2. AFTER TRY')
      } finally {
        console.log('3. FINALLY')
      }
    
    }
    
    main()
    
    更新 通过@martin的回答,我意识到这就是Node.js的行为

    我编写了一个可复制的程序来演示如何在
    try{}
    块中退出Node.js,并使用代码0退出,而不运行
    finally{}
    块,这非常简单:等待一个永不解决的承诺

    async function main() {
      try {
        await new Promise(r => console.log('IN TRY BLOCK'))
      } finally {
        console.log('IN FINALLY BLOCK')
      }
    }
    
    main()
    
    上述程序将仅在TRY块中输出
    ,并以代码0退出,而在FINALLY块
    中根本不输出


    对于那些觉得这也很奇怪的读者,我还为node在

    上打开了一个问题,你想实现什么?为什么你要创造和观察,然后立即将其转化为承诺

    如果你需要处理“事件流”,你可以创建一个可观察的

    这是一个使用观察值的例子,不知何故是从你的观察值中派生出来的

    import {BehaviorSubject} from 'rxjs/Rx'
    
    const subject = new BehaviorSubject<number>(-1)
    const obs = subject.asObservable().share();
    
    console.log('1. BEFORE SUBCRIPTION');
    obs
    .subscribe(
        aNumber => console.log('2. PROCESSING SUBCRIPTION', aNumber),
        err => console.error(err),
        () => console.log('3. COMPLETED OBSERVABLE')
    )
    
    subject.next(0);
    subject.next(1);
    subject.next(2);
    subject.complete();
    
    从'rxjs/Rx'导入{BehaviorSubject}
    const subject=新行为主体(-1)
    const obs=subject.asObservable().share();
    console.log('1.在子描述之前');
    obs
    .订阅(
    aNumber=>console.log('2.处理子描述',aNumber),
    err=>console.error(err),
    ()=>console.log('3.COMPLETED OBSERVABLE')
    )
    主题。下一个(0);
    主题。下一(1);
    主题。下一(2);
    subject.complete();
    
    由于您使用的运算符,这实际上是正确的行为

    您正在创建一个
    BehaviorSubject(-1)
    ,它向每个新订户发出
    -1
    。然后您就有了
    share()
    ,该始终只保留一个对其源可观察订阅的

    这里是最重要的。当您使用
    obs.subscribe()
    时,它使
    share
    订阅其源(
    subject
    事实上),该源立即发出
    -1
    ,但该值不会打印在任何地方,因为您使用了带有
    .subscribe()
    的空订阅服务器

    然后你用
    wait obs.first()
    从未解决,因此
    等待
    将永远等待

    但是,如果使用而不是
    obs.subscribe()
    ,例如:

    obs.take(1).subscribe(console.log);
    
    请参阅控制台输出:


    。。。您将看到预期的输出,因为
    take(1)
    在收到
    -1
    后立即取消订阅,然后第二个订阅者
    toPromise()
    使
    share()
    再次订阅
    subject
    ,发出
    -1
    ,承诺成功解决。

    如果
    .toPromise()
    将永远无法解决,程序应该永远在那里等待。但是,结果是程序以代码0退出。请运行代码,您将发现它立即退出。这是两件不同的事情。
    main
    方法是
    async
    ,因此它只返回一个承诺,并继续执行。然而,承诺仍然没有得到解决,
    wait
    将永远等待。您可以在这里看到,
    wait
    之后的任何内容都不会执行:。当程序结束时,表示偶数循环中没有更多的事件(在演示中是这样),但这与本例无关。您能解释一下为什么不执行这段代码吗
    console.log('2.AFTER TRY')
    因为它是在前一个承诺由于
    wait
    而得到解决之后执行的,这是因为
    setTimeout
    创建了另一个安排在60秒内的事件。在您的演示中,事件循环中没有更多的事件,因此结束。我将代码缩短,以证明它将立即退出,而无需在
    finally{}
    块中运行代码,这是非常有线的。
    obs.take(1).subscribe(console.log);