typescript - 为什么在这段代码中使用 RxJS pipe() 操作符来封装单个 map() 操作符而不是链接多个 RxJS 操作符?
问题描述
我不太喜欢 RxJs。我正在关注基于 Angular+RxJS 的 Angular 视频课程,但我有以下疑问。基本上,它创建了一个服务类,该类调用返回 JSON 的 REST API,如下所示:
{
"payload":[
{
"id":1,
"description":"Serverless Angular with Firebase Course",
"longDescription":"Serveless Angular with Firestore, Firebase Storage & Hosting, Firebase Cloud Functions & AngularFire",
"iconUrl":"https://s3-us-west-1.amazonaws.com/angular-university/course-images/serverless-angular-small.png",
"lessonsCount":10,
"category":"BEGINNER",
"seqNo":6,
"url":"serverless-angular",
"price":50
},
{
"id":2,
"description":"Angular Core Deep Dive",
"longDescription":"A detailed walk-through of the most important part of Angular - the Core and Common modules",
"iconUrl":"https://s3-us-west-1.amazonaws.com/angular-university/course-images/angular-core-in-depth-small.png",
"lessonsCount":10,
"category":"BEGINNER",
"seqNo":3,
"url":"angular-core-course",
"price":50
},
{
"id":3,
"description":"RxJs In Practice Course",
"longDescription":"Understand the RxJs Observable pattern, learn the RxJs Operators via practical examples",
"iconUrl":"https://s3-us-west-1.amazonaws.com/angular-university/course-images/rxjs-in-practice-course.png",
"courseListIcon":"https://angular-academy.s3.amazonaws.com/main-logo/main-page-logo-small-hat.png",
"category":"BEGINNER",
"lessonsCount":10,
"seqNo":2,
"url":"rxjs-course",
"price":50
},
{
"id":4,
"description":"NgRx (with NgRx Data) - The Complete Guide",
"longDescription":"Learn the modern Ngrx Ecosystem, including NgRx Data, Store, Effects, Router Store, Ngrx Entity, and Dev Tools.",
"iconUrl":"https://angular-university.s3-us-west-1.amazonaws.com/course-images/ngrx-v2.png",
"category":"BEGINNER",
"lessonsCount":10,
"seqNo":1,
"url":"ngrx-course",
"promo":false,
"price":50
},
{
"id":5,
"description":"Angular for Beginners",
"longDescription":"Establish a solid layer of fundamentals, learn what's under the hood of Angular",
"iconUrl":"https://angular-academy.s3.amazonaws.com/thumbnails/angular2-for-beginners-small-v2.png",
"courseListIcon":"https://angular-academy.s3.amazonaws.com/main-logo/main-page-logo-small-hat.png",
"category":"BEGINNER",
"lessonsCount":10,
"seqNo":4,
"url":"angular-for-beginners",
"price":50
},
{
"id":6,
"description":"Angular Security Course - Web Security Fundamentals",
"longDescription":"Learn Web Security Fundamentals and apply them to defend an Angular / Node Application from multiple types of attacks.",
"iconUrl":"https://s3-us-west-1.amazonaws.com/angular-university/course-images/security-cover-small-v2.png",
"courseListIcon":"https://s3-us-west-1.amazonaws.com/angular-university/course-images/lock-v2.png",
"category":"ADVANCED",
"lessonsCount":11,
"seqNo":9,
"url":"angular-security-course",
"price":50
},
{
"id":7,
"description":"Angular PWA - Progressive Web Apps Course",
"longDescription":"Learn Angular Progressive Web Applications, build the future of the Web Today.",
"iconUrl":"https://s3-us-west-1.amazonaws.com/angular-university/course-images/angular-pwa-course.png",
"courseListIcon":"https://s3-us-west-1.amazonaws.com/angular-university/course-images/alien.png",
"category":"ADVANCED",
"lessonsCount":8,
"seqNo":10,
"url":"angular-pwa-course",
"price":50
},
{
"id":8,
"description":"Angular Advanced Library Laboratory: Build Your Own Library",
"longDescription":"Learn Advanced Angular functionality typically used in Library Development. Advanced Components, Directives, Testing, Npm",
"iconUrl":"https://angular-academy.s3.amazonaws.com/thumbnails/advanced_angular-small-v3.png",
"courseListIcon":"https://angular-academy.s3.amazonaws.com/thumbnails/angular-advanced-lesson-icon.png",
"category":"ADVANCED",
"seqNo":11,
"url":"angular-advanced-course",
"price":50
},
{
"id":9,
"description":"The Complete Typescript Course",
"longDescription":"Complete Guide to Typescript From Scratch: Learn the language in-depth and use it to build a Node REST API.",
"iconUrl":"https://angular-academy.s3.amazonaws.com/thumbnails/typescript-2-small.png",
"courseListIcon":"https://angular-academy.s3.amazonaws.com/thumbnails/typescript-2-lesson.png",
"category":"BEGINNER",
"seqNo":12,
"url":"typescript-course",
"price":50
},
{
"id":11,
"description":"Angular Material Course",
"longDescription":"Build Applications with the official Angular Widget Library",
"iconUrl":"https://s3-us-west-1.amazonaws.com/angular-university/course-images/material_design.png",
"category":"BEGINNER",
"seqNo":14,
"url":"angular-material-course",
"price":50
},
{
"id":12,
"description":"Angular Testing Course",
"longDescription":"In-depth guide to Unit Testing and E2E Testing of Angular Applications",
"iconUrl":"https://s3-us-west-1.amazonaws.com/angular-university/course-images/angular-testing-small.png",
"category":"BEGINNER",
"seqNo":5,
"url":"angular-testing-course",
"lessonsCount":10,
"promo":false,
"price":50
},
{
"id":14,
"description":"NestJs In Practice (with MongoDB)",
"longDescription":"Build a modern REST backend using Typescript, MongoDB and the familiar Angular API.",
"iconUrl":"https://angular-university.s3-us-west-1.amazonaws.com/course-images/nestjs-v2.png",
"category":"BEGINNER",
"lessonsCount":10,
"seqNo":8,
"url":"nestjs-course",
"promo":false,
"price":50
},
{
"id":16,
"description":"Stripe Payments In Practice",
"longDescription":"Build your own ecommerce store & membership website with Firebase, Stripe and Express",
"iconUrl":"https://angular-university.s3-us-west-1.amazonaws.com/course-images/stripe-course.jpg",
"lessonsCount":10,
"category":"BEGINNER",
"seqNo":7,
"url":"stripe-course",
"price":50
},
{
"id":17,
"description":"Reactive Angular Course",
"longDescription":"How to build Angular applications in Reactive style using plain RxJs - Patterns and Anti-Patterns",
"iconUrl":"https://angular-university.s3-us-west-1.amazonaws.com/course-images/reactive-angular-course.jpg",
"courseListIcon":"https://angular-academy.s3.amazonaws.com/main-logo/main-page-logo-small-hat.png",
"category":"BEGINNER",
"lessonsCount":10,
"seqNo":0,
"url":"reactive-angular-course",
"price":50
}
]
}
如您所见,它包含一个包含 n 个对象的有效负载属性。本教程显示,从发出此有效负载属性的 Observable 开始,它将返回另一个仅发出数组的 Observable。
这是建议的解决方案:
@Injectable({
providedIn: 'root'
})
export class CoursesService {
constructor(private http:HttpClient) {}
loadedAllCourses(): Observable<Course[]> {
// The obsarvable return a JSON containing the "payload" property containing the array
//return this.http.get<Course[]>("/api/courses");
return this.http.get<Course[]>("/api/courses")
.pipe(
map(res => res["payload"])
);
}
}
现在我知道map()运算符在 Observable 上工作并返回另一个 Observable “修改”通过传递给原始 Observable 的箭头函数(在这种情况下,我正在访问API 调用响应的有效负载字段的内容,我我正在创建一个仅包含有效负载字段内容的新 Observable。很清楚。
我无法理解的是:为什么这个map()运算符是在pipe()运算符中定义的。根据我阅读官方文档的理解,pipe()运算符用于以声明方式链接多个运算符(例如:应用 OPERATOR 1,在 OPERATOR 1(即 Observable)的输出上应用 OPERATOR 2 并返回另一个可观察等。
这个推理正确吗?在前一种情况下,我只有一个map()运算符,所以理论上我可以直接在get()方法返回的 Observable 上使用map()运算符(直接在包含 API 响应的 Observable 上)。这样对吗?
为什么在本课程中,当只应用一个运算符时,教员总是使用pipe()运算符?(如前一种情况)。这是一种约定还是“错误”?
解决方案
在本课程中,讲师始终使用 pipe() 运算符,因为从 RxJs 6 开始,他们使用可管道运算符,这来自官方文档 - https://rxjs.dev/guide/v6/pipeable-operators。
关于您使用地图的方式,“pluck”运算符似乎更适合您的情况:
this.http.get<Course[]>("/api/courses")
.pipe(
pluck("payload")
);
推荐阅读
- php - 如何修复数据库中的 utf-8
- ruby-on-rails - 搜索 has_many 与 Searchkick 的关联
- html - 数字输入 - 文本略低于中心,直到您单击框
- python - Python 中的数据类型不匹配尝试使用一些 twitter 数据更新 Sqlite3 数据库
- sql - 访问追加查询重复结果
- android - 如何从使用 create-react-native-app 构建的 Android 应用程序中删除短信和通话权限?
- html - 隐藏在内容后面的子菜单
- python - Tkinter - 我如何更改标题?
- php - 我的 SQL 查询在 PHP 上是错误的,但在 phpmyadmin 上有效
- java - 如何在不使用正则表达式的情况下检查字符串格式?