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:
- Your
fetchLyricsfunction doesn't return anything (it just subscribes to the observable internally). When you call it, there's no value to assign tograb. - HTTP calls (and RxJS observables in general) are asynchronous. You can't just "return" a value from inside a
subscribecallback 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:
switchMapcancels any pending lyric requests if a new suggestion query comes in (ideal for autocomplete-style flows where users type quickly).forkJoinwaits for all lyric requests to finish before emitting results. If you want to update items as their lyrics load, replaceforkJoinwithmerge.- We pair each lyric result with its original item so we can correctly assign the data back to the right song.
内容的提问来源于stack exchange,提问作者user6885115
相关产品推荐
相关产品推荐

