最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - .toPromise() and lastValueFrom() in rxjs - Stack Overflow

programmeradmin1浏览0评论

I have this observable

createMyRecord(): Observable<myRecord> {
        return of(TEMPLATE_DB).pipe(
            mergeMap((template) => doTask(template)),
            mergeMap(() => EMPTY)
        );
    }

I call it with

await createMyRecord().toPromise();

.toPromise() is deprecated, so I would like to change the call with lastValueFrom():

await lastValueFrom(createMyRecord());

but I receive the following error:

EmptyError
no elements in sequence

UPDATE: for now, resolved with:

 await lastValueFrom(createMyRecord()).catch((err) => {
            if (err instanceof EmptyError) {
                log.info("OK");
            }
        });

but is there a better solution?

I have this observable

createMyRecord(): Observable<myRecord> {
        return of(TEMPLATE_DB).pipe(
            mergeMap((template) => doTask(template)),
            mergeMap(() => EMPTY)
        );
    }

I call it with

await createMyRecord().toPromise();

.toPromise() is deprecated, so I would like to change the call with lastValueFrom():

await lastValueFrom(createMyRecord());

but I receive the following error:

EmptyError
no elements in sequence

UPDATE: for now, resolved with:

 await lastValueFrom(createMyRecord()).catch((err) => {
            if (err instanceof EmptyError) {
                log.info("OK");
            }
        });

but is there a better solution?

Share Improve this question edited Apr 19, 2024 at 7:40 user1 asked Aug 26, 2021 at 13:41 user1user1 5862 gold badges8 silver badges23 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 11

lastValueFrom now takes a configuration parameter as its second parameter, and you can specify a default value that will be emitted if the observable is empty:

await rxjs.lastValueFrom(observableThing, {defaultValue: "oh no - empty!"})

Is there a better solution?

Yes and no.

In your case mergeMap(_ => EMPTY) will ensure that your observable completes without emitting a value. Promises resolve to a value or they error. So the only thing to do here that meets the spec is to throw an error.

A work-around

You can sidestep this by emitting something. For example, here I emit null after the source completes:

createMyRecord(): Observable<myRecord> {
  return of(TEMPLATE_DB).pipe(
    mergeMap((template) => doTask(template)),
    mergeMap(() => EMPTY),
    s => concat(s, of(null as myRecord))
  );
}

Now your promise will resolve with a null once the observable completes successfully.

Something idiomatic

Rather than changing your code, you can change how you call it. This way you don't need to worry about how Observables and Promises interact.

Instead of await lastValueFrom(createMyRecord()); write:

createMyRecord().subscribe();
发布评论

评论列表(0)

  1. 暂无评论