简体   繁体   中英

how can i get last value from a Observable?

i try to get last value from a observable. the example code is

// RxJS v6+
import { lastValueFrom, Subject } from 'rxjs';
import { scan } from 'rxjs/operators';

async function main() {
  const subject = new Subject();

  const example = subject.pipe(
    scan((acc, curr) => {
      return Object.assign({}, acc, curr);
    }, {}),
  );
  const subscribe = example.subscribe((val) =>
    console.log('Accumulated object:', val),
  );
  subject.next({ name: 'Joe' });
  subject.next({ age: 30 });
  subject.next({ favoriteLanguage: 'JavaScript' });

  console.log('+++++++++++++');
  const resp = await lastValueFrom(example);
  console.log(resp);
  console.log('end');
}

main()
  .catch((e) => {
    console.error(e);
  })
  .finally(async () => {
    console.log('final');
  });

the output is

➜  npns-service git:(mr/master/658) ✗ ts-node prisma/test.ts
Accumulated object: { name: 'Joe' }
Accumulated object: { name: 'Joe', age: 30 }
Accumulated object: { name: 'Joe', age: 30, favoriteLanguage: 'JavaScript' }
+++++++++++++

i can't got the resp output message.

how can i got the resp value from example Observable?

Update your code to complete your observable:

setTimeout(() => { // setTimeout is just a simple way to use JS's event loop
    subject.next({ name: 'Joe' });
    subject.next({ age: 30 });
    subject.next({ favoriteLanguage: 'JavaScript' });
    subject.complete(); // signal that our observable is done emitting
    // subject.next(something) here would do 
    // nothing, the observable is complete 
}, 0);

console.log('+++++++++++++');
const resp = await lastValueFrom(example);
console.log(resp);
console.log('end');


If you don't complete an observable, as far as your run-time is aware it may still emit something else in a minute, 5 hours, next year - who knows? There must be some condition that triggers completion.

A quick aside: I threw the code that emits on your subject into the event loop so that the code that follows can await it. Otherwise your subject would complete synchronously before that code was ever run.

Update 1: how can i got a newest value from a observable?

Make example an observable that remembers (buffers) the last emission. Then just use take(1) to read the buffered value.

const subject = new Subject();

const example = subject.pipe(
    scan((acc, curr) => Object.assign({}, acc, curr), {}),
    shareReplay(1)
);
example.subscribe(val =>
    console.log('Accumulated object:', val)
);

subject.next({ name: 'Joe' });
subject.next({ age: 30 });
subject.next({ favoriteLanguage: 'JavaScript' });

console.log('+++++++++++++');
const resp = await lastValueFrom(example.pipe(take(1));
console.log(resp);
console.log('end');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM