簡體   English   中英

RxJs - 從同一 observable 中的 observable 獲取最后發出的值

[英]RxJs - Get last emitted value from observable within same observable

我有一個 observable,我希望使用 observable 發出的前一個值來發出下一個值(這將用於防止多次執行相同的昂貴操作)

interface PersonInfo {
  name: string;
  data: string;
}

const names$ = new Subject<string[]>();
const personInfo$ = new BehaviorSubject<PersonInfo[]>([]);

const namesData$ = names$.pipe(
  // Rather than getting the latest value from personInfo$ i would like to use the last value emitted by this observable
  withLatestFrom(personInfo$),
  map(([names, personsInfo]) => {
    // Remove persons who do not have a name in the names$
    const persons = personsInfo.filter((personInfo) =>
      names.includes(personInfo.name)
    );

    names.forEach((name) => {
      if (!persons.some((person) => person.name === name)) {
        persons.push({ name, data: getPersonData(name) });
      }
    });

    personInfo$.next(persons);
    return persons;
  })
);

const getPersonData = (name: string) => {
  // This is an expensive operation and we do not wish to call it multiple times
  console.log(`getPersonsData called by ${name}`);
  return name;
};

這是我到目前為止提出的,雖然它按預期工作,但我覺得這是不好的做法,我真的不想依賴 personInfo$ BehaviourSubject。 我嘗試使用 withLatestFrom(namesData$),但這不起作用有兩個原因:

  • namesData$ 在初始化之前被訪問
  • 由於 withLatestFrom 至少需要發射一次,因此 observable 將永遠不會發射。

是否有一些管道/其他聰明的方法可以做到這一點,而不必像我一樣使用額外的(不必要的)可觀察的?

StackBlitz

據我了解, personData只是來自getPersonsData的數據的緩存,所以最好是對象而不是 Observable、BehaviourSubject 或數組

這是我的完整解決方案

interface PersonInfo {
  name: string;
  data: string;
}

const names$ = new Subject<string[]>();
const personData: {[key: string]: string} = {};

const namesData$ = names$.pipe(
  map(names) => {
    return names.map(name => {
        if (personData[name]) {
            return {name, data: personData[name]};
        } else {
            const data = getPersonData(name);
            personData[name] = data;
            return {name, data};
        }
    });
  })
);

const getPersonData = (name: string) => {
  // This is an expensive operation and we do not wish to call it multiple times
  console.log(`getPersonsData called by ${name}`);
  return name;
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM