【问题标题】:Calling asynchronous function but returning result synchronously调用异步函数但同步返回结果
【发布时间】:2019-09-30 07:05:32
【问题描述】:

我想构造一个函数来创建并返回一个Observable。根据此函数接收的参数,它应该创建Observable 并直接返回它,或者(在特殊情况下)在返回Observable 之前调用另一个异步函数。

抽象例子:

async function doSomethingAsync(){
    return 'success';
}

function returnObservable(specialCase: boolean): Observable<any>
    const observable = new Observable(
        observer =>
            observer.next(1)
        }
    );

    if(specialCase) {
        doSomethingAsync().then(
            then => {
                // this does not work, of course, but that's what I would like to be able to do
                return observable;
            }
        )       
    } else {
        return observable;
    }
} 

现在我的问题是我不能调用异步函数然后返回Observable。我可以使整个 returnObservable 函数异步,而只是 await doSomethingAsync 但随后 returnObservable 函数将返回 Promise 返回 Observable - 这不是我想要的。此函数的使用者应该直接接收 Observable。

我希望我能把我的问题说清楚。有什么办法可以解决这个问题吗?

【问题讨论】:

  • 一旦你的代码变成异步的 - 其余的也将是异步的,它是病毒式的。
  • @zerkms - 说得很好。但由于 OP 正在返回一种异步构造(和Observable),所以还是有希望的。 :-)
  • @zerkms “这是病毒式的”......哈哈。
  • @T.J.Crowder 我从 GPL 中重用了它,这被称为“病毒许可”en.wikipedia.org/wiki/Viral_license /cc briosheje

标签: javascript typescript promise rxjs observable


【解决方案1】:

将 Promise 转换为 observable:

async function doSomethingAsync(){
    return 'success';
}

function returnObservable(specialCase: boolean): Observable<any>
    const observable = new Observable(
        observer =>
            observer.next(1)
        }
    );

    if(specialCase) {
        return Observable.from(doSomethingAsync().then(
            then => {
                // this does not work, of course, but that's what I would like to be able to do
                return observable;
            }
        ));
    }
    return observable;
} 

【讨论】:

  • 这将返回一个 Observable,当 specialCase == true 时发出一个 Observable。代码应该是return from(doSomethingAsync()).pipe(switchMap(val =&gt; observable));
  • 确切地说,消费者不应该处理另一个 Observable。 @fridoo 的解决方案正是我想要的。
【解决方案2】:

有没有办法解决这个问题?

因为您返回的是Observable,所以可能有。

async 函数返回之前,不可能让returnObservable 同步阻塞。 但是,您可以让它返回一个Observable,它(可选)在异步函数完成之前不会发出任何事件。你甚至可以让它不调用异步函数,直到/除非有订阅它。

有点像:

function returnObservable(specialCase: boolean): Observable<any>
    const promise = specialCase ? doSomethingAsync() : Promise.resolve();
    const observable = new Observable(
        observer => {
            promise
            .then(() => {
                observer.next(1);
            })
            .catch(error => {
                // deal with the error
            });
        }
    );

    return observable;
} 

(你甚至可以使用fromPromise。我在 Rx.js 上还不够强大,无法确定。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-22
    • 2020-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-07
    相关资源
    最近更新 更多