如何用外部化函数替换 map() 运算符中定义的箭头函数?

Posted

技术标签:

【中文标题】如何用外部化函数替换 map() 运算符中定义的箭头函数?【英文标题】:How can I replace an arrow function defined into map() operator with an externalized function? 【发布时间】:2020-11-04 16:56:08 【问题描述】:

我还没有接触到 Angular 和 TypeScript,我对如何重构我的代码有以下疑问。

在我的 TypeScript 组件类代码中,我有这样的内容:

this.eventService.getEvents().subscribe(eventsSnaps => 
  this.events = eventsSnaps.map(currentEventSnap => 
    //console.log("DOCUMENT ID: ", currentCourseSnap.payload.doc.id);
    //console.log("DATA: ", currentCourseSnap.payload.doc.data());
    var currentEvent = 
      id: currentEventSnap.payload.doc.id,
      ...currentEventSnap.payload.doc.data()
    ;

    var date = currentEventSnap.payload.doc.data().start.toDate()
    var hour = date.getHours();

    var startDateAsString = this.fromDateToString(date);

    console.log("startDateAsString: ", startDateAsString);
    console.log("hour: ", hour);

    currentEvent.start = startDateAsString;

    if(hour === 7) 
      currentEvent['backgroundColor'] = 'red';
    
    else if(hour === 15) 
      currentEvent['backgroundColor'] = 'green';
    
    else if(hour === 23) 
      currentEvent['backgroundColor'] = 'black';
    

    return currentEvent;     
  );
  console.log("EVENTS FROM SNAPS: ", this.events);
);

这段代码运行良好,基本上它订阅了一个 Observable,其中包含从 Firebase Firestore 数据库检索到的数据,并对这些检索到的数据执行一些逻辑。

我的问题是,在我的代码中,我需要执行多个订阅(对不同的服务方法),这些订阅执行与 ma​​p() 箭头函数中定义的完全相同的逻辑。

我的想法是将所有这些逻辑外部化为一个函数,该函数将传递给我的代码中需要实现此行为的所有 map() 函数。会不会是个好主意?

在 casi 中,我如何定义一个封装此逻辑的函数并将其用作我在之前 ma​​p() 中定义的箭头函数的替换,这还不错?

【问题讨论】:

【参考方案1】:

这很简单,也是一个很好的问题。你可以使用 rxjs map 操作符来完成这个任务:

const eventSnaps$ = this.eventService.getEvents().pipe(
  map(events => events.map(currentEventSnap => 
    //console.log("DOCUMENT ID: ", currentCourseSnap.payload.doc.id);
    //console.log("DATA: ", currentCourseSnap.payload.doc.data());
    var currentEvent = 
      id: currentEventSnap.payload.doc.id,
      ...currentEventSnap.payload.doc.data()
    ;

    var date = currentEventSnap.payload.doc.data().start.toDate()
    var hour = date.getHours();

    var startDateAsString = this.fromDateToString(date);

    console.log("startDateAsString: ", startDateAsString);
    console.log("hour: ", hour);

    currentEvent.start = startDateAsString;

    if(hour === 7) 
      currentEvent['backgroundColor'] = 'red';
    
    else if(hour === 15) 
      currentEvent['backgroundColor'] = 'green';
    
    else if(hour === 23) 
      currentEvent['backgroundColor'] = 'black';
    

    return currentEvent;     
  )
)

eventSnaps$.subscribe(eventsSnaps => 
  this.events = eventsSnaps;
  console.log("EVENTS FROM SNAPS: ", this.events);
);

如果您提前一步,您可以进一步重构您的代码并将 rxjs 映射移动到一个单独的函数中:

function mapEventsToEventsSnaps(events) => events.map(currentEventSnap => 
    //console.log("DOCUMENT ID: ", currentCourseSnap.payload.doc.id);
    //console.log("DATA: ", currentCourseSnap.payload.doc.data());
    var currentEvent = 
      id: currentEventSnap.payload.doc.id,
      ...currentEventSnap.payload.doc.data()
    ;

    var date = currentEventSnap.payload.doc.data().start.toDate()
    var hour = date.getHours();

    var startDateAsString = this.fromDateToString(date);

    console.log("startDateAsString: ", startDateAsString);
    console.log("hour: ", hour);

    currentEvent.start = startDateAsString;

    if(hour === 7) 
      currentEvent['backgroundColor'] = 'red';
    
    else if(hour === 15) 
      currentEvent['backgroundColor'] = 'green';
    
    else if(hour === 23) 
      currentEvent['backgroundColor'] = 'black';
    

    return currentEvent;     
  );

然后您可以在管道中重新使用该功能。这使您的管道更具可读性,分离您的代码并使函数本身可测试:

const eventsSnaps$ = this.eventService.getEvents().pipe(
  map(events => mapEventsToEventsSnaps(events))
);

【讨论】:

好的,但是我在哪里定义这个函数呢? (我的意思是函数 mapEventsToEventsSnaps(events) )。如果我把它作为我的 TypeScript 类的函数,IDE 会给我以下错误:“意外的令牌。预期的构造函数、方法、访问器或属性。” ***.com/questions/43070702/… 如果你想在一个类中添加你的函数,你不能使用 function 关键字。如果您想在纯 .ts 文件中保护此函数,请将其导出并导入到您可以使用 function 关键字的任何位置。

以上是关于如何用外部化函数替换 map() 运算符中定义的箭头函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何用在浏览器中正确呈现的混合的内部和外部 HTML 内容替换内部 HTML 内容

如何用三元运算符(?:)替换“if”语句?

如何用撇号替换字符串中的双引号(不是指定它是字符串的外部双引号)

如何用C中#define宏中的字符串常量替换函数名

C ++如何用空实现有选择地替换函数

如何用 func 委托替换 Action 委托,将值返回给函数