You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中fetchLyrics函数复用返回undefined问题求助

Hey there, let's break down why grab is coming back as undefined and how to fix this.

The core issue here is two-fold:

  1. Your fetchLyrics function doesn't return anything (it just subscribes to the observable internally). When you call it, there's no value to assign to grab.
  2. HTTP calls (and RxJS observables in general) are asynchronous. You can't just "return" a value from inside a subscribe callback and expect it to be available immediately in synchronous code.

Step 1: Refactor fetchLyrics to return an Observable

Instead of subscribing inside fetchLyrics, return the observable from this.apiService.get(). This lets you handle subscriptions or combine it with other observables wherever you call the function.

fetchLyrics({ artist, song }) { 
  console.log({ artist, song }); 
  // Return the observable instead of subscribing here
  return this.apiService.get(artist, song)
    .pipe(
      tap(res => console.log(res)), // Use tap for side effects like logging
      map(res => res['lyrics']), // Extract lyrics with map operator
      catchError(err => {
        console.log(err);
        // Handle error - return a fallback value or rethrow as needed
        return of('Error fetching lyrics');
      })
    );
}

Step 2: Handle multiple lyric requests in getSuggestions

Since you need to fetch lyrics for every item in res['data'], use forkJoin to run all requests in parallel (or concatMap if you need sequential execution). We'll also assign fetched lyrics back to their corresponding items.

getSuggestions(term) { 
  this.apiService.suggest(term)
    .pipe(
      debounceTime(2000),
      tap(res => console.log(res)),
      switchMap(res => {
        // Create an array of observables for each item's lyric request
        const lyricObservables = res['data'].map(item => {
          return this.fetchLyrics({ artist: item.artist.name, song: item.title })
            .pipe(
              // Pair lyric result with the original item to track which lyric belongs to which song
              map(lyrics => ({ item, lyrics }))
            );
        });

        // Use forkJoin to wait for all requests to complete
        return forkJoin(lyricObservables);
      })
    )
    .subscribe(
      (results) => {
        // Assign lyrics to each item and update properties
        results.forEach(({ item, lyrics }) => {
          item.lyrics = lyrics;
          item.playing = false;
        });
        // Update your songs array with modified items
        this.songs = results.map(({ item }) => item);
      },
      (err) => {
        this.songs = [];
        console.log(err);
      }
    );
}

A few quick notes on the implementation:

  • switchMap cancels any pending lyric requests if a new suggestion query comes in (ideal for autocomplete-style flows where users type quickly).
  • forkJoin waits for all lyric requests to finish before emitting results. If you want to update items as their lyrics load, replace forkJoin with merge.
  • We pair each lyric result with its original item so we can correctly assign the data back to the right song.

内容的提问来源于stack exchange,提问作者user6885115

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:42:55